From c265c501d9021dbea4072d1603feaf115765094c Mon Sep 17 00:00:00 2001 From: Lucas Tortora Date: Mon, 1 Jul 2024 16:21:29 -0300 Subject: [PATCH 01/37] refactor!: reorganized documentation according to the agreed top level structure refactor!: deleted files with "content coming soon" --- docs/content/_snippets/cli-check-install.mdx | 2 +- .../_snippets/initialize-iota-client-cli.mdx | 2 +- docs/content/_snippets/move-summary.mdx | 2 +- .../publish-to-devnet-with-coins.mdx | 2 +- docs/content/about-iota/about-iota.mdx | 38 ++ .../{concepts => about-iota}/components.mdx | 10 +- .../images/iota-tokenomics-flow.png | Bin .../iota-architecture.mdx | 0 .../iota-architecture/consensus.mdx | 0 .../iota-architecture/epochs.mdx | 2 +- .../iota-architecture/images/indexer-arch.png | Bin .../images/txn-lifecycle.png | Bin .../iota-architecture/indexer-functions.mdx | 0 .../iota-architecture/iota-security.mdx | 0 .../iota-architecture/protocol-upgrades.mdx | 0 .../iota-architecture/staking-rewards.mdx | 0 .../transaction-lifecycle.mdx | 6 +- .../research-papers.mdx | 0 .../{concepts => about-iota}/tokenomics.mdx | 0 .../tokenomics/gas-in-iota.mdx | 0 .../tokenomics/gas-pricing.mdx | 2 +- .../tokenomics/images/gas-fees-explorer.png | Bin .../tokenomics/iota-bridging.mdx | 0 .../tokenomics/iota-coin.mdx | 0 .../tokenomics/proof-of-stake.mdx | 2 +- .../tokenomics/staking-unstaking.mdx | 0 .../tokenomics/storage-fund.mdx | 0 .../tokenomics/validators-staking.mdx | 0 docs/content/concepts.mdx | 38 -- docs/content/concepts/app-devs.mdx | 33 -- docs/content/concepts/architecture.mdx | 6 - docs/content/concepts/cryptography/system.mdx | 6 - .../system/intents-for-validation.mdx | 6 - .../system/validator-signatures.mdx | 6 - .../data-management-things.mdx | 6 - .../concepts/iota-architecture/high-level.mdx | 6 - .../patterns/app-extensions.mdx | 6 - .../{guides => }/developer/advanced.mdx | 10 +- .../developer/advanced/asset-tokenization.mdx | 8 +- .../developer/advanced/custom-indexer.mdx | 0 .../developer/advanced/graphql-migration.mdx | 8 +- .../advanced/move-2024-migration.mdx | 0 .../developer/advanced/stardust-on-move.mdx | 10 +- docs/content/developer/app-examples.mdx | 22 ++ .../developer/app-examples/blackjack.mdx | 6 +- .../developer/app-examples/coin-flip.mdx | 26 +- .../developer/app-examples/e2e-counter.mdx | 10 +- .../developer/app-examples/plinko.mdx | 2 +- .../developer/app-examples/recaptcha.mdx | 6 +- .../developer/app-examples/tic-tac-toe.mdx | 0 .../app-examples/trustless-token-swap.mdx | 29 ++ .../trustless-token-swap/backend.mdx | 8 +- .../trustless-token-swap/frontend.mdx | 6 +- .../trustless-token-swap/indexer-api.mdx | 4 +- .../developer/app-examples/weather-oracle.mdx | 14 +- .../explanations}/cryptography.mdx | 6 +- .../explanations}/images/zklogin-apple1.png | Bin .../explanations}/images/zklogin-apple2.png | Bin .../explanations}/images/zklogin-apple3.png | Bin .../explanations}/images/zklogin-apple4.png | Bin .../images/zklogin-facebook1.png | Bin .../images/zklogin-facebook2.png | Bin .../explanations}/images/zklogin-flow.png | Bin .../explanations}/images/zklogin-google1.png | Bin .../explanations}/images/zklogin-google2.png | Bin .../explanations}/images/zklogin-google3.png | Bin .../explanations}/images/zklogin-kakao1.png | Bin .../explanations}/images/zklogin-kakao2.png | Bin .../explanations}/images/zklogin-kakao3.png | Bin .../explanations}/images/zklogin-slack1.png | Bin .../explanations}/images/zklogin-slack2.png | Bin .../explanations}/images/zklogin-slack3.png | Bin .../explanations}/images/zklogin-twitch1.png | Bin .../explanations}/images/zklogin-twitch2.png | Bin .../system/checkpoint-verification.mdx | 0 .../explanations}/transaction-auth.mdx | 10 +- .../images/iota_multisig_structures.png | Bin .../transaction-auth/intent-signing.mdx | 2 +- .../transaction-auth/keys-addresses.mdx | 0 .../transaction-auth/multisig.mdx | 6 +- .../transaction-auth/offline-signing.mdx | 4 +- .../transaction-auth/signatures.mdx | 16 +- .../cryptography/explanations}/zklogin.mdx | 6 +- .../explanations}/zklogin/images/overview.png | Bin .../explanations}/zklogin/zklogin-example.mdx | 2 +- .../cryptography/how-to}/cryptography.mdx | 12 +- .../cryptography/how-to}/ecvrf.mdx | 0 .../cryptography/how-to}/groth16.mdx | 0 .../cryptography/how-to}/hashing.mdx | 0 .../cryptography/how-to}/signing.mdx | 2 +- .../developer/dev-cheat-sheet.mdx | 0 .../{guides => developer}/developer.mdx | 16 +- .../{guides => }/developer/evm-to-move.mdx | 0 .../developer/evm-to-move/creating-nft.mdx | 2 +- .../developer/evm-to-move/creating-token.mdx | 8 +- .../developer/evm-to-move/tooling-apis.mdx | 2 +- .../developer/evm-to-move/why-move.mdx | 0 .../exchange-integration.mdx | 4 +- .../stardust-migration.mdx | 0 docs/content/developer/getting-started.mdx | 34 ++ .../developer/getting-started/connect.mdx | 10 +- .../getting-started}/first-app/build-test.mdx | 10 +- .../first-app/client-tssdk.mdx | 4 +- .../getting-started}/first-app/debug.mdx | 2 +- .../getting-started/first-app}/first-app.mdx | 12 +- .../getting-started}/first-app/publish.mdx | 11 +- .../first-app/write-package.mdx | 2 +- .../developer/getting-started/get-address.mdx | 6 +- .../developer/getting-started/get-coins.mdx | 6 +- .../developer/getting-started/graphql-rpc.mdx | 20 +- .../developer/getting-started/images/fork.png | Bin .../getting-started/images/gh-url.png | Bin .../getting-started/images/releases.png | Bin .../getting-started/iota-environment.mdx | 6 +- .../getting-started/iota-install.mdx | 12 +- .../getting-started/local-network.mdx | 2 +- .../{concepts => developer}/graphql-rpc.mdx | 6 +- docs/content/{ => developer}/guides.mdx | 22 +- .../{guides => }/developer/iota-101.mdx | 12 +- .../developer/iota-101/access-time.mdx | 0 .../iota-101/create-coin}/create-coin.mdx | 12 +- .../iota-101/create-coin/in-game-token.mdx | 2 +- .../iota-101/create-coin/loyalty.mdx | 2 +- .../iota-101/create-coin/regulated.mdx | 4 +- .../developer/iota-101/create-nft.mdx | 0 .../iota-move-concepts/collections.mdx | 12 +- .../iota-move-concepts/conventions.mdx | 0 .../iota-move-concepts/entry-functions.mdx | 0 .../iota-101}/iota-move-concepts/init.mdx | 0 .../iota-move-concepts.mdx | 38 +- .../iota-move-concepts/move-on-iota.mdx | 0 .../iota-move-concepts/one-time-witness.mdx | 0 .../packages/custom-policies.mdx | 4 +- .../iota-move-concepts/packages}/packages.mdx | 6 +- .../iota-move-concepts/packages/upgrade.mdx | 4 +- .../iota-101}/iota-move-concepts/patterns.mdx | 2 +- .../patterns/capabilities.mdx | 0 .../patterns/hot-potato.mdx | 0 .../patterns/id-pointer.mdx | 0 .../patterns/transferrable-witness.mdx | 0 .../iota-move-concepts/patterns/witness.mdx | 0 .../iota-101}/iota-move-concepts/strings.mdx | 0 .../dynamic-fields}/dynamic-fields.mdx | 2 +- .../objects}/dynamic-fields/tables-bags.mdx | 2 +- .../iota-101/objects}/events.mdx | 2 +- .../iota-101/objects}/object-model.mdx | 4 +- .../object-ownership/address-owned.mdx | 0 .../objects}/object-ownership/immutable.mdx | 0 .../object-ownership}/object-ownership.mdx | 10 +- .../objects}/object-ownership/shared.mdx | 0 .../objects}/object-ownership/wrapped.mdx | 0 .../iota-101/objects}/shared-owned.mdx | 2 +- .../objects}/transfers/custom-rules.mdx | 0 .../objects}/transfers/transfer-to-object.mdx | 2 +- .../iota-101/objects/transfers}/transfers.mdx | 4 +- .../iota-101/objects}/versioning.mdx | 0 .../iota-101}/transactions/gas-smashing.mdx | 0 .../transactions/ptb}/building-ptb.mdx | 2 +- .../iota-101/transactions/ptb}/coin-mgt.mdx | 4 +- .../transactions/ptb}/prog-txn-blocks.mdx | 8 +- .../transactions/ptb}/simulating-refs.mdx | 2 +- .../transactions/ptb}/working-with-ptbs.mdx | 14 +- .../transactions}/sign-and-send-txn.mdx | 30 +- .../iota-101/transactions}/sponsor-txn.mdx | 0 .../transactions/sponsored-transactions.mdx | 2 +- .../iota-101/transactions}/transactions.mdx | 4 +- .../developer/iota-101/using-events.mdx | 0 .../standards/closed-loop-token.mdx | 12 +- .../closed-loop-token/action-request.mdx | 6 +- .../coin-token-comparison.mdx | 0 .../standards/closed-loop-token/rules.mdx | 8 +- .../standards/closed-loop-token/spending.mdx | 4 +- .../closed-loop-token/token-policy.mdx | 6 +- .../{ => developer}/standards/coin.mdx | 10 +- .../{ => developer}/standards/deepbook.mdx | 0 .../standards/deepbook/design.mdx | 0 .../standards/deepbook/orders.mdx | 0 .../standards/deepbook/pools.mdx | 0 .../standards/deepbook/query-the-pool.mdx | 0 .../standards/deepbook/routing-a-swap.mdx | 0 .../standards/deepbook/trade-and-swap.mdx | 0 .../{ => developer}/standards/display.mdx | 0 .../standards/images/balance-token-coin.png | Bin .../{ => developer}/standards/kiosk-apps.mdx | 4 +- .../{ => developer}/standards/kiosk.mdx | 0 .../{ => developer/standards}/standards.mdx | 0 .../standards/wallet-standard.mdx | 0 .../stardust/addresses.mdx | 0 .../stardust/claiming.mdx | 0 .../{guides => developer}/stardust/faq.mdx | 0 .../stardust/if-tools.mdx | 0 .../stardust/migration-process.mdx | 0 .../stardust/move-models.mdx | 0 .../stardust/testing.mdx | 0 .../{guides => developer}/stardust/units.mdx | 0 .../{guides => developer}/stardust/vested.mdx | 0 .../advanced/efficient-smart-contracts.mdx | 6 - .../developer/advanced/maximize-reach.mdx | 6 - .../developer/advanced/min-gas-fees.mdx | 6 - .../advanced/security-best-practices.mdx | 6 - .../advanced/wallet-integrations.mdx | 6 - .../content/guides/developer/app-examples.mdx | 22 -- .../guides/developer/app-examples/auction.mdx | 6 - .../app-examples/meta-pricing-oracle.mdx | 6 - .../guides/developer/app-examples/oracle.mdx | 6 - .../developer/app-examples/trusted-swap.mdx | 6 - .../app-examples/trustless-token-swap.mdx | 29 -- .../developer/app-examples/turnip-town.mdx | 6 - .../guides/developer/getting-started.mdx | 34 -- .../guides/developer/starter-templates.mdx | 6 - .../guides/developer/zklogin-onboarding.mdx | 6 - .../{guides => }/operator/archives.mdx | 0 .../{guides => }/operator/data-management.mdx | 14 +- .../content/{guides => }/operator/genesis.mdx | 2 +- .../images/fn-basic-functionality.png | Bin .../images/mysten-cloud-snapshots.png | Bin .../{guides => }/operator/iota-full-node.mdx | 2 +- .../{guides => }/operator/node-tools.mdx | 4 +- .../{guides => }/operator/observability.mdx | 0 .../content/{guides => operator}/operator.mdx | 18 +- .../{guides => }/operator/snapshots.mdx | 4 +- .../operator/validator-committee.mdx | 4 +- .../operator/validator-config.mdx | 2 +- .../{guides => }/operator/validator-tasks.mdx | 0 docs/content/references/cli.mdx | 2 +- docs/content/references/cli/client.mdx | 4 +- docs/content/references/cli/ptb.mdx | 4 +- .../contribute/contribute-to-iota-repos.mdx | 2 +- .../contribute/contribution-process.mdx | 2 +- .../references/contribute/style-guide.mdx | 8 +- docs/content/references/iota-api.mdx | 2 +- docs/content/references/iota-graphql.mdx | 8 +- docs/content/references/move/language.mdx | 6 - docs/content/{ => references}/references.mdx | 0 docs/content/sidebars/about-iota.js | 47 +++ docs/content/sidebars/concepts.js | 207 ---------- docs/content/sidebars/developer.js | 358 ++++++++++++++++++ docs/content/sidebars/guides.js | 233 ------------ docs/content/sidebars/operator.js | 18 + docs/content/sidebars/references.js | 2 +- docs/content/sidebars/standards.js | 44 --- docs/site/docusaurus.config.js | 20 +- docs/site/sidebars.js | 12 +- docs/site/src/pages/index.js | 22 +- docs/site/src/theme/Navbar/Content/index.js | 2 +- docs/site/vercel.json | 98 ----- 246 files changed, 928 insertions(+), 1235 deletions(-) create mode 100644 docs/content/about-iota/about-iota.mdx rename docs/content/{concepts => about-iota}/components.mdx (91%) rename docs/content/{concepts => about-iota}/images/iota-tokenomics-flow.png (100%) rename docs/content/{concepts => about-iota}/iota-architecture.mdx (100%) rename docs/content/{concepts => about-iota}/iota-architecture/consensus.mdx (100%) rename docs/content/{concepts => about-iota}/iota-architecture/epochs.mdx (93%) rename docs/content/{concepts => about-iota}/iota-architecture/images/indexer-arch.png (100%) rename docs/content/{concepts => about-iota}/iota-architecture/images/txn-lifecycle.png (100%) rename docs/content/{concepts => about-iota}/iota-architecture/indexer-functions.mdx (100%) rename docs/content/{concepts => about-iota}/iota-architecture/iota-security.mdx (100%) rename docs/content/{concepts => about-iota}/iota-architecture/protocol-upgrades.mdx (100%) rename docs/content/{concepts => about-iota}/iota-architecture/staking-rewards.mdx (100%) rename docs/content/{concepts => about-iota}/iota-architecture/transaction-lifecycle.mdx (98%) rename docs/content/{concepts => about-iota}/research-papers.mdx (100%) rename docs/content/{concepts => about-iota}/tokenomics.mdx (100%) rename docs/content/{concepts => about-iota}/tokenomics/gas-in-iota.mdx (100%) rename docs/content/{concepts => about-iota}/tokenomics/gas-pricing.mdx (98%) rename docs/content/{concepts => about-iota}/tokenomics/images/gas-fees-explorer.png (100%) rename docs/content/{concepts => about-iota}/tokenomics/iota-bridging.mdx (100%) rename docs/content/{concepts => about-iota}/tokenomics/iota-coin.mdx (100%) rename docs/content/{concepts => about-iota}/tokenomics/proof-of-stake.mdx (98%) rename docs/content/{concepts => about-iota}/tokenomics/staking-unstaking.mdx (100%) rename docs/content/{concepts => about-iota}/tokenomics/storage-fund.mdx (100%) rename docs/content/{concepts => about-iota}/tokenomics/validators-staking.mdx (100%) delete mode 100644 docs/content/concepts.mdx delete mode 100644 docs/content/concepts/app-devs.mdx delete mode 100644 docs/content/concepts/architecture.mdx delete mode 100644 docs/content/concepts/cryptography/system.mdx delete mode 100644 docs/content/concepts/cryptography/system/intents-for-validation.mdx delete mode 100644 docs/content/concepts/cryptography/system/validator-signatures.mdx delete mode 100644 docs/content/concepts/iota-architecture/data-management-things.mdx delete mode 100644 docs/content/concepts/iota-architecture/high-level.mdx delete mode 100644 docs/content/concepts/iota-move-concepts/patterns/app-extensions.mdx rename docs/content/{guides => }/developer/advanced.mdx (81%) rename docs/content/{guides => }/developer/advanced/asset-tokenization.mdx (98%) rename docs/content/{guides => }/developer/advanced/custom-indexer.mdx (100%) rename docs/content/{guides => }/developer/advanced/graphql-migration.mdx (87%) rename docs/content/{guides => }/developer/advanced/move-2024-migration.mdx (100%) rename docs/content/{guides => }/developer/advanced/stardust-on-move.mdx (95%) create mode 100644 docs/content/developer/app-examples.mdx rename docs/content/{guides => }/developer/app-examples/blackjack.mdx (95%) rename docs/content/{guides => }/developer/app-examples/coin-flip.mdx (94%) rename docs/content/{guides => }/developer/app-examples/e2e-counter.mdx (95%) rename docs/content/{guides => }/developer/app-examples/plinko.mdx (99%) rename docs/content/{guides => }/developer/app-examples/recaptcha.mdx (98%) rename docs/content/{guides => }/developer/app-examples/tic-tac-toe.mdx (100%) create mode 100644 docs/content/developer/app-examples/trustless-token-swap.mdx rename docs/content/{guides => }/developer/app-examples/trustless-token-swap/backend.mdx (94%) rename docs/content/{guides => }/developer/app-examples/trustless-token-swap/frontend.mdx (97%) rename docs/content/{guides => }/developer/app-examples/trustless-token-swap/indexer-api.mdx (99%) rename docs/content/{guides => }/developer/app-examples/weather-oracle.mdx (97%) rename docs/content/{concepts => developer/cryptography/explanations}/cryptography.mdx (81%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/images/zklogin-apple1.png (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/images/zklogin-apple2.png (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/images/zklogin-apple3.png (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/images/zklogin-apple4.png (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/images/zklogin-facebook1.png (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/images/zklogin-facebook2.png (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/images/zklogin-flow.png (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/images/zklogin-google1.png (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/images/zklogin-google2.png (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/images/zklogin-google3.png (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/images/zklogin-kakao1.png (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/images/zklogin-kakao2.png (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/images/zklogin-kakao3.png (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/images/zklogin-slack1.png (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/images/zklogin-slack2.png (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/images/zklogin-slack3.png (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/images/zklogin-twitch1.png (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/images/zklogin-twitch2.png (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/system/checkpoint-verification.mdx (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/transaction-auth.mdx (84%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/transaction-auth/images/iota_multisig_structures.png (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/transaction-auth/intent-signing.mdx (98%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/transaction-auth/keys-addresses.mdx (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/transaction-auth/multisig.mdx (97%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/transaction-auth/offline-signing.mdx (95%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/transaction-auth/signatures.mdx (91%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/zklogin.mdx (99%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/zklogin/images/overview.png (100%) rename docs/content/{concepts/cryptography => developer/cryptography/explanations}/zklogin/zklogin-example.mdx (97%) rename docs/content/{guides/developer => developer/cryptography/how-to}/cryptography.mdx (76%) rename docs/content/{guides/developer/cryptography => developer/cryptography/how-to}/ecvrf.mdx (100%) rename docs/content/{guides/developer/cryptography => developer/cryptography/how-to}/groth16.mdx (100%) rename docs/content/{guides/developer/cryptography => developer/cryptography/how-to}/hashing.mdx (100%) rename docs/content/{guides/developer/cryptography => developer/cryptography/how-to}/signing.mdx (97%) rename docs/content/{guides => }/developer/dev-cheat-sheet.mdx (100%) rename docs/content/{guides => developer}/developer.mdx (85%) rename docs/content/{guides => }/developer/evm-to-move.mdx (100%) rename docs/content/{guides => }/developer/evm-to-move/creating-nft.mdx (99%) rename docs/content/{guides => }/developer/evm-to-move/creating-token.mdx (95%) rename docs/content/{guides => }/developer/evm-to-move/tooling-apis.mdx (91%) rename docs/content/{guides => }/developer/evm-to-move/why-move.mdx (100%) rename docs/content/{guides/operator => developer/exchange-integration}/exchange-integration.mdx (97%) rename docs/content/{guides => developer/exchange-integration}/stardust-migration.mdx (100%) create mode 100644 docs/content/developer/getting-started.mdx rename docs/content/{guides => }/developer/getting-started/connect.mdx (86%) rename docs/content/{guides/developer => developer/getting-started}/first-app/build-test.mdx (95%) rename docs/content/{guides/developer => developer/getting-started}/first-app/client-tssdk.mdx (96%) rename docs/content/{guides/developer => developer/getting-started}/first-app/debug.mdx (97%) rename docs/content/{guides/developer => developer/getting-started/first-app}/first-app.mdx (84%) rename docs/content/{guides/developer => developer/getting-started}/first-app/publish.mdx (95%) rename docs/content/{guides/developer => developer/getting-started}/first-app/write-package.mdx (98%) rename docs/content/{guides => }/developer/getting-started/get-address.mdx (91%) rename docs/content/{guides => }/developer/getting-started/get-coins.mdx (80%) rename docs/content/{guides => }/developer/getting-started/graphql-rpc.mdx (83%) rename docs/content/{guides => }/developer/getting-started/images/fork.png (100%) rename docs/content/{guides => }/developer/getting-started/images/gh-url.png (100%) rename docs/content/{guides => }/developer/getting-started/images/releases.png (100%) rename docs/content/{guides => }/developer/getting-started/iota-environment.mdx (97%) rename docs/content/{guides => }/developer/getting-started/iota-install.mdx (96%) rename docs/content/{guides => }/developer/getting-started/local-network.mdx (99%) rename docs/content/{concepts => developer}/graphql-rpc.mdx (94%) rename docs/content/{ => developer}/guides.mdx (63%) rename docs/content/{guides => }/developer/iota-101.mdx (84%) rename docs/content/{guides => }/developer/iota-101/access-time.mdx (100%) rename docs/content/{guides/developer/iota-101 => developer/iota-101/create-coin}/create-coin.mdx (87%) rename docs/content/{guides => }/developer/iota-101/create-coin/in-game-token.mdx (90%) rename docs/content/{guides => }/developer/iota-101/create-coin/loyalty.mdx (93%) rename docs/content/{guides => }/developer/iota-101/create-coin/regulated.mdx (89%) rename docs/content/{guides => }/developer/iota-101/create-nft.mdx (100%) rename docs/content/{concepts => developer/iota-101}/iota-move-concepts/collections.mdx (77%) rename docs/content/{concepts => developer/iota-101}/iota-move-concepts/conventions.mdx (100%) rename docs/content/{concepts => developer/iota-101}/iota-move-concepts/entry-functions.mdx (100%) rename docs/content/{concepts => developer/iota-101}/iota-move-concepts/init.mdx (100%) rename docs/content/{concepts => developer/iota-101/iota-move-concepts}/iota-move-concepts.mdx (74%) rename docs/content/{concepts => developer/iota-101}/iota-move-concepts/move-on-iota.mdx (100%) rename docs/content/{concepts => developer/iota-101}/iota-move-concepts/one-time-witness.mdx (100%) rename docs/content/{concepts => developer/iota-101}/iota-move-concepts/packages/custom-policies.mdx (99%) rename docs/content/{concepts/iota-move-concepts => developer/iota-101/iota-move-concepts/packages}/packages.mdx (91%) rename docs/content/{concepts => developer/iota-101}/iota-move-concepts/packages/upgrade.mdx (98%) rename docs/content/{concepts => developer/iota-101}/iota-move-concepts/patterns.mdx (93%) rename docs/content/{concepts => developer/iota-101}/iota-move-concepts/patterns/capabilities.mdx (100%) rename docs/content/{concepts => developer/iota-101}/iota-move-concepts/patterns/hot-potato.mdx (100%) rename docs/content/{concepts => developer/iota-101}/iota-move-concepts/patterns/id-pointer.mdx (100%) rename docs/content/{concepts => developer/iota-101}/iota-move-concepts/patterns/transferrable-witness.mdx (100%) rename docs/content/{concepts => developer/iota-101}/iota-move-concepts/patterns/witness.mdx (100%) rename docs/content/{concepts => developer/iota-101}/iota-move-concepts/strings.mdx (100%) rename docs/content/{concepts => developer/iota-101/objects/dynamic-fields}/dynamic-fields.mdx (99%) rename docs/content/{concepts => developer/iota-101/objects}/dynamic-fields/tables-bags.mdx (94%) rename docs/content/{concepts => developer/iota-101/objects}/events.mdx (96%) rename docs/content/{concepts => developer/iota-101/objects}/object-model.mdx (97%) rename docs/content/{concepts => developer/iota-101/objects}/object-ownership/address-owned.mdx (100%) rename docs/content/{concepts => developer/iota-101/objects}/object-ownership/immutable.mdx (100%) rename docs/content/{concepts => developer/iota-101/objects/object-ownership}/object-ownership.mdx (77%) rename docs/content/{concepts => developer/iota-101/objects}/object-ownership/shared.mdx (100%) rename docs/content/{concepts => developer/iota-101/objects}/object-ownership/wrapped.mdx (100%) rename docs/content/{guides/developer/iota-101 => developer/iota-101/objects}/shared-owned.mdx (99%) rename docs/content/{concepts => developer/iota-101/objects}/transfers/custom-rules.mdx (100%) rename docs/content/{concepts => developer/iota-101/objects}/transfers/transfer-to-object.mdx (97%) rename docs/content/{concepts => developer/iota-101/objects/transfers}/transfers.mdx (88%) rename docs/content/{concepts => developer/iota-101/objects}/versioning.mdx (100%) rename docs/content/{concepts => developer/iota-101}/transactions/gas-smashing.mdx (100%) rename docs/content/{guides/developer/iota-101 => developer/iota-101/transactions/ptb}/building-ptb.mdx (97%) rename docs/content/{guides/developer/iota-101 => developer/iota-101/transactions/ptb}/coin-mgt.mdx (89%) rename docs/content/{concepts/transactions => developer/iota-101/transactions/ptb}/prog-txn-blocks.mdx (99%) rename docs/content/{guides/developer/iota-101 => developer/iota-101/transactions/ptb}/simulating-refs.mdx (94%) rename docs/content/{guides/developer/iota-101 => developer/iota-101/transactions/ptb}/working-with-ptbs.mdx (50%) rename docs/content/{guides/developer/iota-101 => developer/iota-101/transactions}/sign-and-send-txn.mdx (84%) rename docs/content/{guides/developer/iota-101 => developer/iota-101/transactions}/sponsor-txn.mdx (100%) rename docs/content/{concepts => developer/iota-101}/transactions/sponsored-transactions.mdx (98%) rename docs/content/{concepts => developer/iota-101/transactions}/transactions.mdx (96%) rename docs/content/{guides => }/developer/iota-101/using-events.mdx (100%) rename docs/content/{ => developer}/standards/closed-loop-token.mdx (74%) rename docs/content/{ => developer}/standards/closed-loop-token/action-request.mdx (95%) rename docs/content/{ => developer}/standards/closed-loop-token/coin-token-comparison.mdx (100%) rename docs/content/{ => developer}/standards/closed-loop-token/rules.mdx (88%) rename docs/content/{ => developer}/standards/closed-loop-token/spending.mdx (91%) rename docs/content/{ => developer}/standards/closed-loop-token/token-policy.mdx (95%) rename docs/content/{ => developer}/standards/coin.mdx (95%) rename docs/content/{ => developer}/standards/deepbook.mdx (100%) rename docs/content/{ => developer}/standards/deepbook/design.mdx (100%) rename docs/content/{ => developer}/standards/deepbook/orders.mdx (100%) rename docs/content/{ => developer}/standards/deepbook/pools.mdx (100%) rename docs/content/{ => developer}/standards/deepbook/query-the-pool.mdx (100%) rename docs/content/{ => developer}/standards/deepbook/routing-a-swap.mdx (100%) rename docs/content/{ => developer}/standards/deepbook/trade-and-swap.mdx (100%) rename docs/content/{ => developer}/standards/display.mdx (100%) rename docs/content/{ => developer}/standards/images/balance-token-coin.png (100%) rename docs/content/{ => developer}/standards/kiosk-apps.mdx (95%) rename docs/content/{ => developer}/standards/kiosk.mdx (100%) rename docs/content/{ => developer/standards}/standards.mdx (100%) rename docs/content/{ => developer}/standards/wallet-standard.mdx (100%) rename docs/content/{guides => developer}/stardust/addresses.mdx (100%) rename docs/content/{guides => developer}/stardust/claiming.mdx (100%) rename docs/content/{guides => developer}/stardust/faq.mdx (100%) rename docs/content/{guides => developer}/stardust/if-tools.mdx (100%) rename docs/content/{guides => developer}/stardust/migration-process.mdx (100%) rename docs/content/{guides => developer}/stardust/move-models.mdx (100%) rename docs/content/{guides => developer}/stardust/testing.mdx (100%) rename docs/content/{guides => developer}/stardust/units.mdx (100%) rename docs/content/{guides => developer}/stardust/vested.mdx (100%) delete mode 100644 docs/content/guides/developer/advanced/efficient-smart-contracts.mdx delete mode 100644 docs/content/guides/developer/advanced/maximize-reach.mdx delete mode 100644 docs/content/guides/developer/advanced/min-gas-fees.mdx delete mode 100644 docs/content/guides/developer/advanced/security-best-practices.mdx delete mode 100644 docs/content/guides/developer/advanced/wallet-integrations.mdx delete mode 100644 docs/content/guides/developer/app-examples.mdx delete mode 100644 docs/content/guides/developer/app-examples/auction.mdx delete mode 100644 docs/content/guides/developer/app-examples/meta-pricing-oracle.mdx delete mode 100644 docs/content/guides/developer/app-examples/oracle.mdx delete mode 100644 docs/content/guides/developer/app-examples/trusted-swap.mdx delete mode 100644 docs/content/guides/developer/app-examples/trustless-token-swap.mdx delete mode 100644 docs/content/guides/developer/app-examples/turnip-town.mdx delete mode 100644 docs/content/guides/developer/getting-started.mdx delete mode 100644 docs/content/guides/developer/starter-templates.mdx delete mode 100644 docs/content/guides/developer/zklogin-onboarding.mdx rename docs/content/{guides => }/operator/archives.mdx (100%) rename docs/content/{guides => }/operator/data-management.mdx (89%) rename docs/content/{guides => }/operator/genesis.mdx (88%) rename docs/content/{guides => }/operator/images/fn-basic-functionality.png (100%) rename docs/content/{guides => }/operator/images/mysten-cloud-snapshots.png (100%) rename docs/content/{guides => }/operator/iota-full-node.mdx (99%) rename docs/content/{guides => }/operator/node-tools.mdx (95%) rename docs/content/{guides => }/operator/observability.mdx (100%) rename docs/content/{guides => operator}/operator.mdx (56%) rename docs/content/{guides => }/operator/snapshots.mdx (98%) rename docs/content/{guides => }/operator/validator-committee.mdx (95%) rename docs/content/{guides => }/operator/validator-config.mdx (99%) rename docs/content/{guides => }/operator/validator-tasks.mdx (100%) delete mode 100644 docs/content/references/move/language.mdx rename docs/content/{ => references}/references.mdx (100%) create mode 100644 docs/content/sidebars/about-iota.js delete mode 100644 docs/content/sidebars/concepts.js create mode 100644 docs/content/sidebars/developer.js delete mode 100644 docs/content/sidebars/guides.js create mode 100644 docs/content/sidebars/operator.js delete mode 100644 docs/content/sidebars/standards.js delete mode 100644 docs/site/vercel.json diff --git a/docs/content/_snippets/cli-check-install.mdx b/docs/content/_snippets/cli-check-install.mdx index 275885c257c..0d9ab46c144 100644 --- a/docs/content/_snippets/cli-check-install.mdx +++ b/docs/content/_snippets/cli-check-install.mdx @@ -8,4 +8,4 @@ iota --version If the terminal or console responds with a version number, you already have the IOTA CLI installed. -If the command is not found, follow the instructions in [Install IOTA](/guides/developer/getting-started/iota-install.mdx) to get the IOTA CLI on your system. \ No newline at end of file +If the command is not found, follow the instructions in [Install IOTA](/developer/getting-started/iota-install.mdx) to get the IOTA CLI on your system. \ No newline at end of file diff --git a/docs/content/_snippets/initialize-iota-client-cli.mdx b/docs/content/_snippets/initialize-iota-client-cli.mdx index a72ab945eff..56a544fca85 100644 --- a/docs/content/_snippets/initialize-iota-client-cli.mdx +++ b/docs/content/_snippets/initialize-iota-client-cli.mdx @@ -1,6 +1,6 @@ :::info -See [Publish a Package](/guides/developer/first-app/publish.mdx) for a more detailed guide on publishing packages or [IOTA Client CLI](/references/cli/client.mdx) for a complete reference of `client` commands in the IOTA CLI. +See [Publish a Package](/developer/getting-started/first-app/publish.mdx) for a more detailed guide on publishing packages or [IOTA Client CLI](/references/cli/client.mdx) for a complete reference of `client` commands in the IOTA CLI. ::: diff --git a/docs/content/_snippets/move-summary.mdx b/docs/content/_snippets/move-summary.mdx index df8af37de49..a33a615ec4e 100644 --- a/docs/content/_snippets/move-summary.mdx +++ b/docs/content/_snippets/move-summary.mdx @@ -1 +1 @@ -Move is an open source language for writing safe packages to manipulate on-chain objects (sometimes referred to as "smart contracts"). Move is a platform-agnostic language to enable common libraries, tooling, and developer communities across blockchains with vastly different data and execution models. Move is adaptable to meet the needs of the blockchain the code operates on, see [Move on IOTA](concepts/iota-move-concepts.mdx#differences) to review enhancements made to Move for optimization on the IOTA blockchain. +Move is an open source language for writing safe packages to manipulate on-chain objects (sometimes referred to as "smart contracts"). Move is a platform-agnostic language to enable common libraries, tooling, and developer communities across blockchains with vastly different data and execution models. Move is adaptable to meet the needs of the blockchain the code operates on, see [Move on IOTA](../developer/iota-101/iota-move-concepts/iota-move-concepts.mdx) to review enhancements made to Move for optimization on the IOTA blockchain. diff --git a/docs/content/_snippets/publish-to-devnet-with-coins.mdx b/docs/content/_snippets/publish-to-devnet-with-coins.mdx index b0c77ab9b56..b2676b072f9 100644 --- a/docs/content/_snippets/publish-to-devnet-with-coins.mdx +++ b/docs/content/_snippets/publish-to-devnet-with-coins.mdx @@ -1,4 +1,4 @@ -Before being able to publish your package to Testnet, you need Testnet IOTA tokens. To get some, join the [IOTA Discord](https://discord.gg/IOTA), complete the verification steps, enter the `#testnet-faucet` channel and type `!faucet `. For other ways to get IOTA in your Testnet account, see [Get IOTA Tokens](/guides/developer/getting-started/get-coins). +Before being able to publish your package to Testnet, you need Testnet IOTA tokens. To get some, join the [IOTA Discord](https://discord.gg/IOTA), complete the verification steps, enter the `#testnet-faucet` channel and type `!faucet `. For other ways to get IOTA in your Testnet account, see [Get IOTA Tokens](/developer/getting-started/get-coins). Now that you have an account with some Testnet IOTA, you can deploy your contracts. To publish your package, use the following command in the same terminal or console: diff --git a/docs/content/about-iota/about-iota.mdx b/docs/content/about-iota/about-iota.mdx new file mode 100644 index 00000000000..6afb2caa5c9 --- /dev/null +++ b/docs/content/about-iota/about-iota.mdx @@ -0,0 +1,38 @@ +--- +title: IOTA Concepts Overview +sidebar_label: Overview +--- + +IOTA is different than other blockchains. The concepts explored in this section provide a background to the IOTA blockchain and web3 in general. + +## Move + + + + + + + + +## Objects + + + + + + + +## Cryptography + + + + + + +## Tokenomics + + + + + + diff --git a/docs/content/concepts/components.mdx b/docs/content/about-iota/components.mdx similarity index 91% rename from docs/content/concepts/components.mdx rename to docs/content/about-iota/components.mdx index 26f479cfce4..34a04204efe 100644 --- a/docs/content/concepts/components.mdx +++ b/docs/content/about-iota/components.mdx @@ -31,8 +31,8 @@ IOTA uses a delegated proof-of-stake (DPoS) consensus mechanism to validate on-c To learn more about consensus on IOTA, see the following guides and topics: -- [Validator Committee](guides/operator/validator-committee.mdx) -- [IOTA Full Node Data Management](guides/operator/data-management.mdx) +- [Validator Committee](../operator/validator-committee.mdx) +- [IOTA Full Node Data Management](../operator/data-management.mdx) @@ -47,11 +47,11 @@ IOTA has several networks available, each serving a different purpose. To learn more about these networks and how to interact with them, see the following guides: -- [Create a Local IOTA Network](guides/developer/getting-started/local-network.mdx) -- [Connect to IOTA](guides/developer/getting-started/connect.mdx) +- [Create a Local IOTA Network](../developer/getting-started/local-network.mdx) +- [Connect to IOTA](../developer/getting-started/connect.mdx) ## Move The Move language provides the logic for all activity on IOTA, like trading NFTs, playing IOTA-integrated games (dApps), and all other transaction-based events. The IOTA platform uses a concept novel to earlier blockchains, where blocks on the chain are actually objects that define assets rather than simple key-value stores that define addresses. The increased programmability inherent with objects required a more robust logic engine to maximize the benefits of this new approach to blockchain technology. -To learn more about Move, see [Move Concepts](./iota-move-concepts.mdx). +To learn more about Move, see [Move Concepts](../developer/iota-101/iota-move-concepts/iota-move-concepts.mdx). diff --git a/docs/content/concepts/images/iota-tokenomics-flow.png b/docs/content/about-iota/images/iota-tokenomics-flow.png similarity index 100% rename from docs/content/concepts/images/iota-tokenomics-flow.png rename to docs/content/about-iota/images/iota-tokenomics-flow.png diff --git a/docs/content/concepts/iota-architecture.mdx b/docs/content/about-iota/iota-architecture.mdx similarity index 100% rename from docs/content/concepts/iota-architecture.mdx rename to docs/content/about-iota/iota-architecture.mdx diff --git a/docs/content/concepts/iota-architecture/consensus.mdx b/docs/content/about-iota/iota-architecture/consensus.mdx similarity index 100% rename from docs/content/concepts/iota-architecture/consensus.mdx rename to docs/content/about-iota/iota-architecture/consensus.mdx diff --git a/docs/content/concepts/iota-architecture/epochs.mdx b/docs/content/about-iota/iota-architecture/epochs.mdx similarity index 93% rename from docs/content/concepts/iota-architecture/epochs.mdx rename to docs/content/about-iota/iota-architecture/epochs.mdx index a04d2b9c67c..45489a1bb7c 100644 --- a/docs/content/concepts/iota-architecture/epochs.mdx +++ b/docs/content/about-iota/iota-architecture/epochs.mdx @@ -9,7 +9,7 @@ In a simplified view, epochs are to the IOTA network what individual days are to An epoch is a duration of time where the IOTA validator set and their stakes remain unchanged. On both Mainnet and Testnet, an epoch is about 24 hours. This timeframe allows validators to process transactions efficiently without worrying about ad hoc validator changes during the middle of an epoch. -Epoch values are included in the metadata of transactions on the IOTA network, but the average user is unaffected by its value. The only time a user might need to know about epochs is in the case of expiring transactions, where a transaction is only valid if executed before a set epoch. See [Transactions](../transactions.mdx) for more information about transactions on IOTA. +Epoch values are included in the metadata of transactions on the IOTA network, but the average user is unaffected by its value. The only time a user might need to know about epochs is in the case of expiring transactions, where a transaction is only valid if executed before a set epoch. See [Transactions](../../developer/iota-101/transactions/transactions.mdx) for more information about transactions on IOTA. ## Reconfiguration diff --git a/docs/content/concepts/iota-architecture/images/indexer-arch.png b/docs/content/about-iota/iota-architecture/images/indexer-arch.png similarity index 100% rename from docs/content/concepts/iota-architecture/images/indexer-arch.png rename to docs/content/about-iota/iota-architecture/images/indexer-arch.png diff --git a/docs/content/concepts/iota-architecture/images/txn-lifecycle.png b/docs/content/about-iota/iota-architecture/images/txn-lifecycle.png similarity index 100% rename from docs/content/concepts/iota-architecture/images/txn-lifecycle.png rename to docs/content/about-iota/iota-architecture/images/txn-lifecycle.png diff --git a/docs/content/concepts/iota-architecture/indexer-functions.mdx b/docs/content/about-iota/iota-architecture/indexer-functions.mdx similarity index 100% rename from docs/content/concepts/iota-architecture/indexer-functions.mdx rename to docs/content/about-iota/iota-architecture/indexer-functions.mdx diff --git a/docs/content/concepts/iota-architecture/iota-security.mdx b/docs/content/about-iota/iota-architecture/iota-security.mdx similarity index 100% rename from docs/content/concepts/iota-architecture/iota-security.mdx rename to docs/content/about-iota/iota-architecture/iota-security.mdx diff --git a/docs/content/concepts/iota-architecture/protocol-upgrades.mdx b/docs/content/about-iota/iota-architecture/protocol-upgrades.mdx similarity index 100% rename from docs/content/concepts/iota-architecture/protocol-upgrades.mdx rename to docs/content/about-iota/iota-architecture/protocol-upgrades.mdx diff --git a/docs/content/concepts/iota-architecture/staking-rewards.mdx b/docs/content/about-iota/iota-architecture/staking-rewards.mdx similarity index 100% rename from docs/content/concepts/iota-architecture/staking-rewards.mdx rename to docs/content/about-iota/iota-architecture/staking-rewards.mdx diff --git a/docs/content/concepts/iota-architecture/transaction-lifecycle.mdx b/docs/content/about-iota/iota-architecture/transaction-lifecycle.mdx similarity index 98% rename from docs/content/concepts/iota-architecture/transaction-lifecycle.mdx rename to docs/content/about-iota/iota-architecture/transaction-lifecycle.mdx index 53f99e3db1c..d64226fa373 100644 --- a/docs/content/concepts/iota-architecture/transaction-lifecycle.mdx +++ b/docs/content/about-iota/iota-architecture/transaction-lifecycle.mdx @@ -13,7 +13,7 @@ At a high level, the following figure outlines the life cycle of a transaction o The following steps align with those in the preceding image. -1. The first step of the process is the creation of a transaction. A user with a private key creates and signs a user transaction to either mutate objects they own, or a mix of objects they own and [shared objects](../object-ownership/shared.mdx). +1. The first step of the process is the creation of a transaction. A user with a private key creates and signs a user transaction to either mutate objects they own, or a mix of objects they own and [shared objects](../../developer/iota-101/objects/object-ownership/shared.mdx). 1. IOTA sends the transaction to each validator (often through a Full node). Validators perform a series of validity and safety checks, sign it, and return the signed transaction to the client. @@ -115,7 +115,7 @@ After a validator executes a transaction, it returns signed effects from that tr After the supermajority of validators have executed the transaction, and an effects certificate exists, the effects of the transaction (transfers, newly minted objects, and so on) have been implemented. At this point, the network can process transactions that depend on those effects. -For transactions that involve owned objects only, this happens before consensus in under half a second. If a transaction includes shared objects, it happens shortly after consensus, which can take a few seconds. At this point, the transaction reached settlement finality because now you can process more transactions on the same input objects. See [Object Ownership](../../concepts/object-ownership.mdx) for more information. +For transactions that involve owned objects only, this happens before consensus in under half a second. If a transaction includes shared objects, it happens shortly after consensus, which can take a few seconds. At this point, the transaction reached settlement finality because now you can process more transactions on the same input objects. See [Object Ownership](../../developer/iota-101/objects/object-ownership/object-ownership.mdx) for more information. ## An example path to an effects certificate @@ -161,7 +161,7 @@ Before the Full node sends back an effects certificate to your wallet app, it ma The purpose of this extra step is to keep the Full node up to date as much as possible, especially when the wallet app frequently hits the same Full node. In this coffee shop example, this might be trivial, but for a high frequency application, such as gaming, it could be important. -When an app constructs a transaction, it typically requests that the Full node choose a gas object for it. Gas objects are owned objects, meaning that if the Full node is stale and not aware of the right version of the object, it could lead to invalid transactions, or worse, client equivocation if the client software does not handle it properly. Executing on Full node before returning `EffectsCertificate` is one way to avoid this situation. A request can ask for such behavior by using the `WaitForLocalExecution` parameter. See [Sponsored Transactions](../transactions/sponsored-transactions.mdx) for more on client equivocation. +When an app constructs a transaction, it typically requests that the Full node choose a gas object for it. Gas objects are owned objects, meaning that if the Full node is stale and not aware of the right version of the object, it could lead to invalid transactions, or worse, client equivocation if the client software does not handle it properly. Executing on Full node before returning `EffectsCertificate` is one way to avoid this situation. A request can ask for such behavior by using the `WaitForLocalExecution` parameter. See [Sponsored Transactions](../../developer/iota-101/transactions/sponsored-transactions.mdx) for more on client equivocation. Using `WaitForLocalExecution` is not always the best choice, however. For example, with this coffee payment it adds a layer of end-to-end latency without significant benefits. In this case, using the `WaitForEffects` parameter instead to have a slightly shorter user-perceived latency. diff --git a/docs/content/concepts/research-papers.mdx b/docs/content/about-iota/research-papers.mdx similarity index 100% rename from docs/content/concepts/research-papers.mdx rename to docs/content/about-iota/research-papers.mdx diff --git a/docs/content/concepts/tokenomics.mdx b/docs/content/about-iota/tokenomics.mdx similarity index 100% rename from docs/content/concepts/tokenomics.mdx rename to docs/content/about-iota/tokenomics.mdx diff --git a/docs/content/concepts/tokenomics/gas-in-iota.mdx b/docs/content/about-iota/tokenomics/gas-in-iota.mdx similarity index 100% rename from docs/content/concepts/tokenomics/gas-in-iota.mdx rename to docs/content/about-iota/tokenomics/gas-in-iota.mdx diff --git a/docs/content/concepts/tokenomics/gas-pricing.mdx b/docs/content/about-iota/tokenomics/gas-pricing.mdx similarity index 98% rename from docs/content/concepts/tokenomics/gas-pricing.mdx rename to docs/content/about-iota/tokenomics/gas-pricing.mdx index fc39cc98fbb..41c4aaf28b3 100644 --- a/docs/content/concepts/tokenomics/gas-pricing.mdx +++ b/docs/content/about-iota/tokenomics/gas-pricing.mdx @@ -26,7 +26,7 @@ On the IOTA network, a single $ReferencePrice$ exists throughout each epoch, wit More generally, the IOTA gas price mechanism makes the $ReferencePrice$ a credible anchor for you to reference when submitting transactions to the network. Providing reasonable confidence that transactions submitted with gas prices at or close to the reference price are executed in a timely manner. This is achieved through three core steps: -- **Gas price survey:** All validators are surveyed at the start of each epoch, and every validator submits their reservation price. That is, each validator states the minimum gas price at which they are willing to process transactions. The protocol orders these quotes and chooses the 2/3 percentile by stake as the reference price. The gas price survey goal is to set a reference price under which a [quorum](../../guides/operator/validator-committee.mdx#quorums) of validators are willing to promptly process transactions. +- **Gas price survey:** All validators are surveyed at the start of each epoch, and every validator submits their reservation price. That is, each validator states the minimum gas price at which they are willing to process transactions. The protocol orders these quotes and chooses the 2/3 percentile by stake as the reference price. The gas price survey goal is to set a reference price under which a [quorum](../../operator/validator-committee.mdx#quorums) of validators are willing to promptly process transactions. - **Tallying rule:** Throughout the epoch, validators obtain signals over the operations of other validators. Each validator uses these signals to build a (subjective) evaluation over the performance of every other validator. Specifically, each validator constructs a multiplier for the stake rewards of every other validator such that validators who behave well receive boosted rewards, and validators who do not receive reduced rewards. The tallying rule goal is to create a community-enforced mechanism for encouraging validators to honor the reference gas price. - **Incentivized stake reward distribution rule:** At the end of the epoch, the distribution of stake rewards across validators is adjusted using information from the tallying rule. Specifically, a global multiplier is built for every validator using the median value (weighted by stake) out of the set of individual multipliers constructed during the tallying rule. All else equal, validators that operated performantly receive their regular stake rewards, whereas validators who did not operate performantly at the reference gas price receive slashed rewards. Since stake rewards are influenced by the amount of stake each validator owns, validators are encouraged to obtain more stake by lowering gas fees and pricing out inefficient validators. This benefits IOTA end users since the stake reward distribution rule incentivizes validators to deliver a more cost-efficient network. diff --git a/docs/content/concepts/tokenomics/images/gas-fees-explorer.png b/docs/content/about-iota/tokenomics/images/gas-fees-explorer.png similarity index 100% rename from docs/content/concepts/tokenomics/images/gas-fees-explorer.png rename to docs/content/about-iota/tokenomics/images/gas-fees-explorer.png diff --git a/docs/content/concepts/tokenomics/iota-bridging.mdx b/docs/content/about-iota/tokenomics/iota-bridging.mdx similarity index 100% rename from docs/content/concepts/tokenomics/iota-bridging.mdx rename to docs/content/about-iota/tokenomics/iota-bridging.mdx diff --git a/docs/content/concepts/tokenomics/iota-coin.mdx b/docs/content/about-iota/tokenomics/iota-coin.mdx similarity index 100% rename from docs/content/concepts/tokenomics/iota-coin.mdx rename to docs/content/about-iota/tokenomics/iota-coin.mdx diff --git a/docs/content/concepts/tokenomics/proof-of-stake.mdx b/docs/content/about-iota/tokenomics/proof-of-stake.mdx similarity index 98% rename from docs/content/concepts/tokenomics/proof-of-stake.mdx rename to docs/content/about-iota/tokenomics/proof-of-stake.mdx index 1ddd23a77ad..9f9516ab2ee 100644 --- a/docs/content/concepts/tokenomics/proof-of-stake.mdx +++ b/docs/content/about-iota/tokenomics/proof-of-stake.mdx @@ -16,7 +16,7 @@ The IOTA economic model works as follows: At the beginning of each epoch, three important events happen: -- IOTA holders stake (some) of their tokens to validators and a new [committee](../../guides/operator/validator-committee.mdx) is formed. +- IOTA holders stake (some) of their tokens to validators and a new [committee](../../operator/validator-committee.mdx) is formed. - The reference gas prices are set as described in [IOTA Gas Pricing](./gas-pricing.mdx). - The [storage fund](./storage-fund.mdx) size is adjusted using the net inflow of the previous epoch. diff --git a/docs/content/concepts/tokenomics/staking-unstaking.mdx b/docs/content/about-iota/tokenomics/staking-unstaking.mdx similarity index 100% rename from docs/content/concepts/tokenomics/staking-unstaking.mdx rename to docs/content/about-iota/tokenomics/staking-unstaking.mdx diff --git a/docs/content/concepts/tokenomics/storage-fund.mdx b/docs/content/about-iota/tokenomics/storage-fund.mdx similarity index 100% rename from docs/content/concepts/tokenomics/storage-fund.mdx rename to docs/content/about-iota/tokenomics/storage-fund.mdx diff --git a/docs/content/concepts/tokenomics/validators-staking.mdx b/docs/content/about-iota/tokenomics/validators-staking.mdx similarity index 100% rename from docs/content/concepts/tokenomics/validators-staking.mdx rename to docs/content/about-iota/tokenomics/validators-staking.mdx diff --git a/docs/content/concepts.mdx b/docs/content/concepts.mdx deleted file mode 100644 index 57198104940..00000000000 --- a/docs/content/concepts.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: IOTA Concepts Overview -sidebar_label: Overview ---- - -IOTA is different than other blockchains. The concepts explored in this section provide a background to the IOTA blockchain and web3 in general. - -## Move - - - - - - - - -## Objects - - - - - - - -## Cryptography - - - - - - -## Tokenomics - - - - - - diff --git a/docs/content/concepts/app-devs.mdx b/docs/content/concepts/app-devs.mdx deleted file mode 100644 index cad77ca0712..00000000000 --- a/docs/content/concepts/app-devs.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: App Developers ---- - -import MoveSummary from "../_snippets/move-summary.mdx"; - -The topics in this section explore some of the concepts that are of interest to developers creating smart contracts on IOTA. After becoming familiar with these concepts, be sure to check out the [Guides](../guides.mdx) section for instruction on how to implement these concepts in your own code. - -## GraphQL for IOTA RPC - -Basics of the GraphQL service to interact with the IOTA network. - -Go to [GraphQL for IOTA RPC](./graphql-rpc.mdx). - -## Object Model - -The basic unit of storage in IOTA is the object. In contrast to many other blockchains where storage is centered around accounts containing key-value stores, IOTA's storage is centered around objects addressable on-chain by unique IDs. The topics in this section examine the model for objects on IOTA. - -Go to [Object Model](./object-model.mdx). - -## Move Overview - - - -The topics in this section describe some of the key features and coding patterns of Move applied to the IOTA network. - -Go to [Move Overview](./iota-move-concepts.mdx). - -## Transactions - -Transactions define the history of activity on a blockchain. On IOTA, you can develop complex programmable transaction blocks that perform several transaction commands in a single execution. You can also sponsor transactions for your smart contract users to streamline onboarding. The topics in this section explore transactions on IOTA at a conceptual level. - -Go to [Transactions](./transactions.mdx). \ No newline at end of file diff --git a/docs/content/concepts/architecture.mdx b/docs/content/concepts/architecture.mdx deleted file mode 100644 index 31ec640ea0c..00000000000 --- a/docs/content/concepts/architecture.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Architecture -draft: true ---- - -Content coming soon \ No newline at end of file diff --git a/docs/content/concepts/cryptography/system.mdx b/docs/content/concepts/cryptography/system.mdx deleted file mode 100644 index 6118c3b3495..00000000000 --- a/docs/content/concepts/cryptography/system.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: System -draft: true ---- - -Content coming soon \ No newline at end of file diff --git a/docs/content/concepts/cryptography/system/intents-for-validation.mdx b/docs/content/concepts/cryptography/system/intents-for-validation.mdx deleted file mode 100644 index 3f7a5a0de5a..00000000000 --- a/docs/content/concepts/cryptography/system/intents-for-validation.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Intents for Validation -draft: true ---- - -Content coming soon \ No newline at end of file diff --git a/docs/content/concepts/cryptography/system/validator-signatures.mdx b/docs/content/concepts/cryptography/system/validator-signatures.mdx deleted file mode 100644 index 2dc4e8d39e6..00000000000 --- a/docs/content/concepts/cryptography/system/validator-signatures.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Validator Signatures -draft: true ---- - -Content coming soon \ No newline at end of file diff --git a/docs/content/concepts/iota-architecture/data-management-things.mdx b/docs/content/concepts/iota-architecture/data-management-things.mdx deleted file mode 100644 index d2e8fb552e5..00000000000 --- a/docs/content/concepts/iota-architecture/data-management-things.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Archival, Snapshots, Pruning Policies, Indexing -draft: true ---- - -Content coming soon \ No newline at end of file diff --git a/docs/content/concepts/iota-architecture/high-level.mdx b/docs/content/concepts/iota-architecture/high-level.mdx deleted file mode 100644 index e37b9dc9b18..00000000000 --- a/docs/content/concepts/iota-architecture/high-level.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: High Level Diagram -draft: true ---- - -Content coming soon \ No newline at end of file diff --git a/docs/content/concepts/iota-move-concepts/patterns/app-extensions.mdx b/docs/content/concepts/iota-move-concepts/patterns/app-extensions.mdx deleted file mode 100644 index 089a52676a0..00000000000 --- a/docs/content/concepts/iota-move-concepts/patterns/app-extensions.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: App Extensions -draft: true ---- - -Content coming soon \ No newline at end of file diff --git a/docs/content/guides/developer/advanced.mdx b/docs/content/developer/advanced.mdx similarity index 81% rename from docs/content/guides/developer/advanced.mdx rename to docs/content/developer/advanced.mdx index 36143ed26c1..d28ab722c1b 100644 --- a/docs/content/guides/developer/advanced.mdx +++ b/docs/content/developer/advanced.mdx @@ -2,7 +2,7 @@ title: Advanced Topics --- -import MigrateToGraphql from "../../_snippets/migrate-to-graphql.mdx"; +import MigrateToGraphql from "../_snippets/migrate-to-graphql.mdx"; Information in the Advanced Topics section covers coding practices, useful features, and other developer-focused considerations that might arise as you continue your development journey on IOTA. The topics in this section aren't necessarily more difficult than other topics, but they include subjects you might not encounter or need to consider until you're developing more advanced solutions on the IOTA network. @@ -10,13 +10,13 @@ Information in the Advanced Topics section covers coding practices, useful featu Asset tokenization refers to the process of representing real-world assets, such as real estate, art, commodities, stocks, or other valuable assets, as digital tokens on the blockchain network. This involves converting the ownership or rights of an asset into digital tokens, which are then recorded and managed on the blockchain. -Go to [Asset Tokenization](./advanced/asset-tokenization.mdx). +Go to [Asset Tokenization](advanced/asset-tokenization.mdx). ## Custom Indexer You can build custom indexers using the IOTA micro-data ingestion framework. To create an indexer, you subscribe to a checkpoint stream with full checkpoint content. Establishing a custom indexer helps improve latency, allows pruning the data of your IOTA Full node, and provides efficient assemblage of checkpoint data. -Go to [Custom Indexer](./advanced/custom-indexer.mdx). +Go to [Custom Indexer](advanced/custom-indexer.mdx). ## Migrating to GraphQL @@ -24,10 +24,10 @@ See the Migrating to GraphQL guide to upgrade your smart contracts to use the Gr -Go to [Migrating to GraphQL](./advanced/graphql-migration.mdx). +Go to [Migrating to GraphQL](advanced/graphql-migration.mdx). ## Stardust on Move Stardust on Move refers to the migration from IOTA Stardust to the IOTA Move-based ledger. -Go to [Stardust on Move](./advanced/stardust-on-move.mdx). +Go to [Stardust on Move](advanced/stardust-on-move.mdx). diff --git a/docs/content/guides/developer/advanced/asset-tokenization.mdx b/docs/content/developer/advanced/asset-tokenization.mdx similarity index 98% rename from docs/content/guides/developer/advanced/asset-tokenization.mdx rename to docs/content/developer/advanced/asset-tokenization.mdx index 23baf7721dd..1d41910e14b 100644 --- a/docs/content/guides/developer/advanced/asset-tokenization.mdx +++ b/docs/content/developer/advanced/asset-tokenization.mdx @@ -3,7 +3,7 @@ title: Asset Tokenization description: Learn how to tokenize assets on the IOTA blockchain. Asset tokenization refers to the process of representing real-world assets, such as real estate, art, commodities, stocks, or other valuable assets, as digital tokens on the blockchain network. --- -import InitializeIOTAClientCli from "../../../_snippets/initialize-iota-client-cli.mdx"; +import InitializeIOTAClientCli from "../../_snippets/initialize-iota-client-cli.mdx"; Asset tokenization refers to the process of representing real-world assets, such as real estate, art, commodities, stocks, or other valuable assets, as digital tokens on the blockchain network. This involves converting the ownership or rights of an asset into digital tokens, which are then recorded and managed on the blockchain. @@ -58,7 +58,7 @@ Select a module to view its details: The `tokenized_asset` module operates in a manner similar to the `coin` library. -When it receives a new [one-time witness](concepts/iota-move-concepts/one-time-witness.mdx) type, it creates a unique representation of a fractional asset. This module employs similar implementations to some methods found in the `Coin` module. It encompasses functionalities pertinent to asset tokenization, including new asset creation, minting, splitting, joining, and burning. +When it receives a new [one-time witness](../iota-101/iota-move-concepts/one-time-witness.mdx) type, it creates a unique representation of a fractional asset. This module employs similar implementations to some methods found in the `Coin` module. It encompasses functionalities pertinent to asset tokenization, including new asset creation, minting, splitting, joining, and burning. @@ -777,7 +777,7 @@ For more details regarding this process, please consult the setup folder's [READ -## WebAssembly (WASM) and template package {#webassembly-wasm-and-template-package} +## WebAssembly (WASM) and template package :::tip @@ -789,7 +789,7 @@ This feature was developed with the intent to enable Move bytecode serialization In the case of asset tokenization, these edits allow you to create and publish new types that represent physical or digital assets that we want to tokenize. -### Bytecode manipulation {#bytecode-manipulation} +### Bytecode manipulation :::caution diff --git a/docs/content/guides/developer/advanced/custom-indexer.mdx b/docs/content/developer/advanced/custom-indexer.mdx similarity index 100% rename from docs/content/guides/developer/advanced/custom-indexer.mdx rename to docs/content/developer/advanced/custom-indexer.mdx diff --git a/docs/content/guides/developer/advanced/graphql-migration.mdx b/docs/content/developer/advanced/graphql-migration.mdx similarity index 87% rename from docs/content/guides/developer/advanced/graphql-migration.mdx rename to docs/content/developer/advanced/graphql-migration.mdx index 07987490f31..e00f9df6e8b 100644 --- a/docs/content/guides/developer/advanced/graphql-migration.mdx +++ b/docs/content/developer/advanced/graphql-migration.mdx @@ -2,11 +2,11 @@ title: Migrating to GraphQL --- -import MigrateToGraphql from "../../../_snippets/migrate-to-graphql.mdx"; +import MigrateToGraphql from "../../_snippets/migrate-to-graphql.mdx"; -For a comprehensive list of all available GraphQL features, consult the [reference](../../../references/iota-graphql). +For a comprehensive list of all available GraphQL features, consult the [reference](../../references/iota-graphql.mdx). ### Example 1: Get total transaction blocks @@ -145,6 +145,6 @@ The cursor is now passed in the `after` (or `before`) fields on the connection, ## Related links -- [GraphQL reference](../../../references/iota-graphql.mdx): Auto-generated GraphQL reference for IOTA RPC. +- [GraphQL reference](../../references/iota-graphql.mdx): Auto-generated GraphQL reference for IOTA RPC. - [GraphQL quick-start](../getting-started/graphql-rpc.mdx): Querying IOTA RPC with GraphQL gets you started using GraphQL to query the IOTA RPC for on-chain data. -- [GraphQL concepts](../../../concepts/graphql-rpc.mdx): GraphQL for IOTA RPC examines the elements of GraphQL that you should know to get the most from the service. \ No newline at end of file +- [GraphQL concepts](../graphql-rpc.mdx): GraphQL for IOTA RPC examines the elements of GraphQL that you should know to get the most from the service. \ No newline at end of file diff --git a/docs/content/guides/developer/advanced/move-2024-migration.mdx b/docs/content/developer/advanced/move-2024-migration.mdx similarity index 100% rename from docs/content/guides/developer/advanced/move-2024-migration.mdx rename to docs/content/developer/advanced/move-2024-migration.mdx diff --git a/docs/content/guides/developer/advanced/stardust-on-move.mdx b/docs/content/developer/advanced/stardust-on-move.mdx similarity index 95% rename from docs/content/guides/developer/advanced/stardust-on-move.mdx rename to docs/content/developer/advanced/stardust-on-move.mdx index 83022e8dd5f..a7856d2699c 100644 --- a/docs/content/guides/developer/advanced/stardust-on-move.mdx +++ b/docs/content/developer/advanced/stardust-on-move.mdx @@ -29,9 +29,9 @@ crate. This document will give a high to mid-level overview of the migration pro Foundry Outputs in Stardust represent the capability to control the supply of user-defined Native Tokens. In Move, there are established ways for these operations, in particular using -[`Coin`](../../../references/framework/iota-framework/coin.md#resource-coin) and -[`TreasuryCap`](../../../references/framework/iota-framework/coin.md#resource-treasurycap). The two main goals of the -foundry migration are to convert it to a [`CoinManager`](../../../references/framework/iota-framework/coin_manager.md), +[`Coin`](../../references/framework/iota-framework/coin.md#resource-coin) and +[`TreasuryCap`](../../references/framework/iota-framework/coin.md#resource-treasurycap). The two main goals of the +foundry migration are to convert it to a [`CoinManager`](../../references/framework/iota-framework/coin_manager.md), a type introduced in the Move IOTA framework in order to simplify working with the `TreasuryCap`, and to a `Coin` to hold the IOTA tokens of the foundry itself. @@ -67,7 +67,7 @@ the minted coin, it is left at the zero address. This means they were burned in also burned on the Move ledger, as no one controls the `0x0` address. In Move, the `TreasuryCap` type uses a `u64` representation (within -[`Balance`](../../../references/framework/iota-framework/balance.md#struct-balance)) as its maximum supply. Since +[`Balance`](../../references/framework/iota-framework/balance.md#struct-balance)) as its maximum supply. Since Stardust allows for `u256` to be used, in some rare cases, the maximum or circulating supply may exceed the maximum value representable by `u64` (`MAX_U64_SUPPLY`, which here refers to `2^64 - 2` for technical reasons). If the maximum supply exceeds it, it is truncated to `MAX_U64_SUPPLY`, which is fine since no more than `MAX_U64_SUPPLY` tokens were @@ -99,7 +99,7 @@ the `owner` of `B` to the address of `A` (the Alias ID), which is equivalent to the same as if `B` would have been transferred (using either of `iota::transfer::{transfer,public_transfer}`) to the address of `A` (the Alias ID). The migrated alias `A` can then _receive_ `B` using the `stardust::address_unlock_condition::unlock_alias_address_owned_basic` function, which is essentially a wrapper around -[`iota::transfer::receive`](../../../references/framework/iota-framework/transfer#function-receive). There are +[`iota::transfer::receive`](../../references/framework/iota-framework/transfer#function-receive). There are equivalent unlock functions for the other possible variants of object ownership. ## Basic Outputs diff --git a/docs/content/developer/app-examples.mdx b/docs/content/developer/app-examples.mdx new file mode 100644 index 00000000000..9a6bb7377ff --- /dev/null +++ b/docs/content/developer/app-examples.mdx @@ -0,0 +1,22 @@ +--- +title: App Examples +description: Ever-growing list of example packages that demonstrate solutions built on the IOTA blockchain, written by IOTA and Move experts. Use these examples to learn IOTA and Move, and to extract techniques you can apply to your own IOTA projects. +--- + +import WarnMlRpcs from "../_snippets/warn-ml-rpcs.mdx"; + +The ever-growing number of examples in this section showcase packages for the IOTA blockchain. Extract techniques used in these examples to apply to your own IOTA projects as they are written by IOTA and Move experts. + + + +## Examples + +IOTA is dedicated to providing a wide range of examples to guide you in proper programming techniques for the IOTA blockchain. This list will continue to grow, so check back often. + +- [Blackjack](app-examples/blackjack.mdx): This example demonstrates the logic behind an on-chain version of the popular casino card game, Blackjack. +- [Coin Flip](app-examples/coin-flip.mdx): The Coin Flip app demonstrates on-chain randomness. +- [Distributed Counter](app-examples/e2e-counter.mdx): An end-to-end example that creates a basic decentralized counter that anyone can increment, but only the object owner can reset it. The example includes Move code to create the package and leverages the IOTA TypeScript SDK to provide a basic frontend. +- [Plinko](app-examples/plinko.mdx): This example puts the classic Plinko game on chain, demonstrating use of cryptography-based strategies to create a fair and transparent game of chance. +- [Tic-tac-toe](app-examples/tic-tac-toe.mdx): Three implementations of the classic tic-tac-toe game on the IOTA network to demonstrate different approaches to user interaction. +- [Trustless Token Swap](app-examples/trustless-token-swap.mdx): This example demonstrates trustless token swaps on the IOTA blockchain using a shared object as an escrow account. +- [Weather Oracle](app-examples/weather-oracle.mdx): The IOTA Weather Oracle demonstrates how to create a basic weather oracle that provides real-time weather data. diff --git a/docs/content/guides/developer/app-examples/blackjack.mdx b/docs/content/developer/app-examples/blackjack.mdx similarity index 95% rename from docs/content/guides/developer/app-examples/blackjack.mdx rename to docs/content/developer/app-examples/blackjack.mdx index f535ebf719d..5e997ecf67e 100644 --- a/docs/content/guides/developer/app-examples/blackjack.mdx +++ b/docs/content/developer/app-examples/blackjack.mdx @@ -10,7 +10,7 @@ Building an on-chain blackjack game shares a lot of similarities with a coin fli :::info -For more details on building a backend and deploying to IOTA, check out the [Coin Flip app example](./coin-flip.mdx). +For more details on building a backend and deploying to IOTA, check out the [Coin Flip app example](coin-flip.mdx). You can also find the [full repository for this example here](https://github.com/MystenLabs/blackjack-iota). @@ -47,7 +47,7 @@ For testing purposes, the module provides special functions like `get_house_admi ### Counter module -The next module, [`counter_nft.move`](https://github.com/MystenLabs/blackjack-iota/blob/main/move/blackjack/sources/counter_nft.move), introduces the Counter NFT, a key component in the game's mechanics. It serves as the [verifiable random function (VRF)](../cryptography/ecvrf.mdx) input, ensuring uniqueness in each game. The Counter NFT's value increases after each use, maintaining its distinctiveness for every new request. For first-time players, the creation of a Counter NFT is mandatory. To enhance user experience, the user interface can automate this process by integrating the Counter NFT's creation with the game initiation in a single transaction block. This seamless integration simplifies the process for the player, allowing them to focus on the gameplay. This counter serves the same purpose as the one in the [Coin Flip example](./coin-flip.mdx). +The next module, [`counter_nft.move`](https://github.com/MystenLabs/blackjack-iota/blob/main/move/blackjack/sources/counter_nft.move), introduces the Counter NFT, a key component in the game's mechanics. It serves as the [verifiable random function (VRF)](../cryptography/how-to/ecvrf.mdx) input, ensuring uniqueness in each game. The Counter NFT's value increases after each use, maintaining its distinctiveness for every new request. For first-time players, the creation of a Counter NFT is mandatory. To enhance user experience, the user interface can automate this process by integrating the Counter NFT's creation with the game initiation in a single transaction block. This seamless integration simplifies the process for the player, allowing them to focus on the gameplay. This counter serves the same purpose as the one in the [Coin Flip example](coin-flip.mdx). ## Backend @@ -127,7 +127,7 @@ The main sub-directories are: - **State Management:** In both games, state management is crucial. For blackjack, this involves managing the player and dealer's hands and scores using React state hooks. In Satoshi Coin Flip, the state is managed through Move structs like `HouseData`, which track the house's balance and other game-related details. -- **Randomness and Fair Play:** Both games emphasize randomness for fairness. Blackjack uses a Counter NFT and player mouse movements to generate randomness, while Satoshi Coin Flip only uses a Counter NFT as a unique input for the [Verifiable Random Function (VRF)](../cryptography/ecvrf.mdx) in each game. +- **Randomness and Fair Play:** Both games emphasize randomness for fairness. Blackjack uses a Counter NFT and player mouse movements to generate randomness, while Satoshi Coin Flip only uses a Counter NFT as a unique input for the [Verifiable Random Function (VRF)](../cryptography/how-to/ecvrf.mdx) in each game. - **Smart Contract Interactions:** Each game involves smart contract interactions for game actions like placing bets, dealing cards (Blackjack), or making guesses (Coin Flip). These interactions are crucial for executing the game's logic on the blockchain. diff --git a/docs/content/guides/developer/app-examples/coin-flip.mdx b/docs/content/developer/app-examples/coin-flip.mdx similarity index 94% rename from docs/content/guides/developer/app-examples/coin-flip.mdx rename to docs/content/developer/app-examples/coin-flip.mdx index ed43def5a67..ae778dd1f7f 100644 --- a/docs/content/guides/developer/app-examples/coin-flip.mdx +++ b/docs/content/developer/app-examples/coin-flip.mdx @@ -2,8 +2,8 @@ title: Coin Flip --- -import InitializeIOTAClientCli from "../../../_snippets/initialize-iota-client-cli.mdx"; -import PublishToDevnetWithCoins from "../../../_snippets/publish-to-devnet-with-coins.mdx"; +import InitializeIOTAClientCli from "../../_snippets/initialize-iota-client-cli.mdx"; +import PublishToDevnetWithCoins from "../../_snippets/publish-to-devnet-with-coins.mdx"; This guide demonstrates writing a module (smart contract) in Move, deploying it on Devnet, and adding a TypeScript frontend to communicate with the module. @@ -17,7 +17,7 @@ As with all IOTA dApps, a Move package on chain powers the logic of Satoshi Coin ### House module -This example uses several modules to create a package for the Satoshi Coin Flip game. The first module is `house_data.move`. You need to store the game’s data somewhere, and in this module you create a [shared object](concepts/object-ownership/shared.mdx) for all house data. +This example uses several modules to create a package for the Satoshi Coin Flip game. The first module is `house_data.move`. You need to store the game’s data somewhere, and in this module you create a [shared object](../iota-101/objects/object-ownership/shared.mdx) for all house data. :::info @@ -56,7 +56,7 @@ There are few details to take note of in this code: 1. The first line declares the module name as `house_data` within the package `satoshi_flip`. 1. Seven lines begin with the `use` keyword, which enables this module to use types and functions declared in other modules (in this case, they are all coming from the IOTA standard library). 1. Two error codes. These codes are used in assertions and unit tests to ensure that the program is running as intended. -1. Two [`friend`, or trusted, modules](guides/developer/dev-cheat-sheet.mdx#general). +1. Two [`friend`, or trusted, modules](../dev-cheat-sheet.mdx#general). Next, add some more code to this module: @@ -90,9 +90,9 @@ Next, add some more code to this module: ``` - The first struct, `HouseData`, stores the most essential information pertaining to the game. -- The second struct, `HouseCap`, is a [capability](concepts/iota-move-concepts/patterns/capabilities.mdx) that initializes the house data. -- The third struct, `HOUSE_DATA`, is a [one-time witness](concepts/iota-move-concepts/one-time-witness.mdx) that ensures only a single instance of this `HouseData` ever exists. -- The [`init` function](concepts/iota-move-concepts/init.mdx) creates and sends the `Publisher` and `HouseCap` objects to the sender. +- The second struct, `HouseCap`, is a [capability](../iota-101/iota-move-concepts/patterns/capabilities.mdx) that initializes the house data. +- The third struct, `HOUSE_DATA`, is a [one-time witness](../iota-101/iota-move-concepts/one-time-witness.mdx) that ensures only a single instance of this `HouseData` ever exists. +- The [`init` function](../iota-101/iota-move-concepts/init.mdx) creates and sends the `Publisher` and `HouseCap` objects to the sender. So far, you've set up the data structures within the module. Now, create a function that initializes the house data and shares the `HouseData` object: @@ -288,7 +288,7 @@ This code also adds a `count` function that returns the current count, and a tes ### Game module -Lastly, you need a game module and object that can create a new game, distribute funds after the game, and potentially cancel games. Because this is a one-player game, create an [address-owned object](concepts/object-ownership/address-owned.mdx) rather than a [shared object](/concepts/object-ownership/shared.mdx). +Lastly, you need a game module and object that can create a new game, distribute funds after the game, and potentially cancel games. Because this is a one-player game, create an [address-owned object](../iota-101/objects/object-ownership/address-owned.mdx) rather than a [shared object](../iota-101/objects/object-ownership/shared.mdx). Create the game module. In the `sources` directory, create a new file called `single_player_satoshi.move` and populate with the following: @@ -344,7 +344,7 @@ module satoshi_flip::single_player_satoshi { This code follows the same pattern as the others. First, you include the respective imports, although this time the imports are not only from the standard library but also include modules created previously in this example. You also create several constants (in upper case), as well as constants used for errors (Pascal case prefixed with `E`). -Lastly in this section, you also create structs for two [events](concepts/events.mdx) to emit. Indexers consume emitted events, which enables you to track these events through API services, or your own indexer. In this case, the events are for when a new game begins (`NewGame`) and for the outcome of a game when it has finished (`Outcome`). +Lastly in this section, you also create structs for two [events](../iota-101/objects/events.mdx) to emit. Indexers consume emitted events, which enables you to track these events through API services, or your own indexer. In this case, the events are for when a new game begins (`NewGame`) and for the outcome of a game when it has finished (`Outcome`). Add a struct to the module: @@ -414,7 +414,7 @@ Now take a look at the main function in this game, `finish_game`: } ``` -- First, the function makes sure the `Game` object exists, then deletes it, as after the game concludes the metadata is no longer needed. Freeing up unnecessary storage is not only recommended, but [incentivized through rebates on storage fees](concepts/tokenomics/storage-fund.mdx#incentives). +- First, the function makes sure the `Game` object exists, then deletes it, as after the game concludes the metadata is no longer needed. Freeing up unnecessary storage is not only recommended, but [incentivized through rebates on storage fees](../../about-iota/tokenomics/storage-fund.mdx#storage-fund-incentives-incentives). - In step 1, the function checks to see if the BLS signature is valid. This is to ensure the game is truly random. - In step 2, the function checks to see if the player’s guess, heads (`0`) or tails (`1`), is the same as that of the house. This is done by taking the first byte of the randomized vector and checking to see if it’s divisible by two. If it is, it is heads, if it is not, it is tails. - In step 3, if the player won, meaning the player’s guess matched the results of the house, the logic transfers fees from the stake to the house, then distributes the rest of the principle plus an equal amount from the house’s balance back to the player. If the player loses, the logic transfers the entire stake to the house, and takes no fees. @@ -616,7 +616,7 @@ Structure the project folder according to the UI layout, meaning that all Player ### Exploring the code -The UI interacts with the [Single Player smart contract](guides/developer/app-examples/coin-flip.mdx#game-module) variant of the game. This section walks you through each step in the smart contract flow and the corresponding frontend code. +The UI interacts with the [Single Player smart contract](#game-module) variant of the game. This section walks you through each step in the smart contract flow and the corresponding frontend code. :::info @@ -763,7 +763,7 @@ Okay, that’s a good start to have an overview of the project. Time to move to }} ``` -To use a [programmable transaction block](/concepts/transactions/prog-txn-blocks.mdx) (PTB) in IOTA, create a `TransactionBlock`. To initiate a Move call, you must know the global identifier of a public function in your smart contract. The global identifier usually takes the following form: +To use a [programmable transaction block](../iota-101/transactions/ptb/prog-txn-blocks.mdx) (PTB) in IOTA, create a `TransactionBlock`. To initiate a Move call, you must know the global identifier of a public function in your smart contract. The global identifier usually takes the following form: ``` ${PACKAGE_ID}::${MODULE_NAME}::${FUNCTION_NAME} @@ -839,7 +839,7 @@ export function useFetchCounterNft() { } ``` -This hook logic is very basic: if there is no current connected wallet, return empty data; otherwise, fetch the `Counter` object and return it. dApp Kit provides a React hook, `useIOTAClientQuery()`, that enables interaction with [IOTA RPC](references/iota-api.mdx) methods. Different RPC methods require different parameters. To fetch the object owned by a known address, use the [`getOwnedObjects` query](/iota-api-ref#iotax_getownedobjects). +This hook logic is very basic: if there is no current connected wallet, return empty data; otherwise, fetch the `Counter` object and return it. dApp Kit provides a React hook, `useIOTAClientQuery()`, that enables interaction with [IOTA RPC](../../references/iota-api.mdx) methods. Different RPC methods require different parameters. To fetch the object owned by a known address, use the [`getOwnedObjects` query](/iota-api-ref#iotax_getownedobjects). Now, pass the address of the connected wallet, as well as the global identifier for the `Counter`. This is in similar format to the global identifier type for function calls: diff --git a/docs/content/guides/developer/app-examples/e2e-counter.mdx b/docs/content/developer/app-examples/e2e-counter.mdx similarity index 95% rename from docs/content/guides/developer/app-examples/e2e-counter.mdx rename to docs/content/developer/app-examples/e2e-counter.mdx index 159adc822a3..d4e0ca1468c 100644 --- a/docs/content/guides/developer/app-examples/e2e-counter.mdx +++ b/docs/content/developer/app-examples/e2e-counter.mdx @@ -2,9 +2,9 @@ title: Distributed Counter --- -import InfoPnpmRequired from "../../../_snippets/info-pnpm-required.mdx"; +import InfoPnpmRequired from "../../_snippets/info-pnpm-required.mdx"; -This example walks you through building a basic distributed counter app, covering the full end-to-end flow connecting your Move code to your client app. The app allows you to create counters that anyone can increment, but only the owner can reset. This example assumes you already have a React App set with dApp Kit, and it's required `Providers` as described in [Client App with IOTA TypeScript SDK](../first-app/client-tssdk.mdx). +This example walks you through building a basic distributed counter app, covering the full end-to-end flow connecting your Move code to your client app. The app allows you to create counters that anyone can increment, but only the owner can reset. This example assumes you already have a React App set with dApp Kit, and it's required `Providers` as described in [Client App with IOTA TypeScript SDK](../getting-started/first-app/client-tssdk.mdx). @@ -43,13 +43,13 @@ mkdir move cd move ``` -Next, use the [IOTA Client CLI](references/cli/client.mdx) to generate a new Move package. If you have [IOTA installed](guides/developer/getting-started/iota-install.mdx), the IOTA CLI is on your system. Run the following command in your terminal or console: +Next, use the [IOTA Client CLI](../../references/cli/client.mdx) to generate a new Move package. If you have [IOTA installed](../getting-started/iota-install.mdx), the IOTA CLI is on your system. Run the following command in your terminal or console: ```bash iota move new counter ``` -This creates a new, empty Move package in a new `move/counter` directory with a [Move.toml](references/move/move-toml.mdx) file, and an empty `sources` directory. +This creates a new, empty Move package in a new `move/counter` directory with a [Move.toml](../../references/move/move-toml.mdx) file, and an empty `sources` directory. Add your Move code under `sources` by creating a new `counter.move` file: @@ -119,7 +119,7 @@ iota client publish --gas-budget 10000000 counter :::info -See [IOTA Client CLI](/references/cli/client.mdx) for more information about `client` commands in the IOTA CLI. +See [IOTA Client CLI](../../references/cli/client.mdx) for more information about `client` commands in the IOTA CLI. ::: diff --git a/docs/content/guides/developer/app-examples/plinko.mdx b/docs/content/developer/app-examples/plinko.mdx similarity index 99% rename from docs/content/guides/developer/app-examples/plinko.mdx rename to docs/content/developer/app-examples/plinko.mdx index e7786148868..14afec35616 100644 --- a/docs/content/guides/developer/app-examples/plinko.mdx +++ b/docs/content/developer/app-examples/plinko.mdx @@ -4,7 +4,7 @@ title: Plinko Plinko is an example implementation of the popular casino game. The Plinko game on IOTA incorporates advanced cryptographic techniques to ensure fairness and transparency. Players drop Plinko balls onto a pegged board, where they randomly fall into slots representing different multipliers. This document details the game's mechanics, cryptographic features, and the methodology for calculating trace paths and verifying signatures. -Building an on-chain Plinko game shares a lot of similarities with the [Coin Flip](./coin-flip.mdx) game and [Blackjack](./blackjack.mdx) game. For that reason, this example covers only the smart contracts (Move modules) and frontend logic. +Building an on-chain Plinko game shares a lot of similarities with the [Coin Flip](coin-flip.mdx) game and [Blackjack](blackjack.mdx) game. For that reason, this example covers only the smart contracts (Move modules) and frontend logic. :::info diff --git a/docs/content/guides/developer/app-examples/recaptcha.mdx b/docs/content/developer/app-examples/recaptcha.mdx similarity index 98% rename from docs/content/guides/developer/app-examples/recaptcha.mdx rename to docs/content/developer/app-examples/recaptcha.mdx index 9284bca08b5..97b94c75a79 100644 --- a/docs/content/guides/developer/app-examples/recaptcha.mdx +++ b/docs/content/developer/app-examples/recaptcha.mdx @@ -4,8 +4,8 @@ description: Write and deploy a smart contract in Move that uses reCAPTCHA to ve draft: true --- -import InitializeIOTAClientCli from "../../../_snippets/initialize-iota-client-cli.mdx"; -import PublishToDevnetWithCoins from "../../../_snippets/publish-to-devnet-with-coins.mdx"; +import InitializeIOTAClientCli from "../../_snippets/initialize-iota-client-cli.mdx"; +import PublishToDevnetWithCoins from "../../_snippets/publish-to-devnet-with-coins.mdx"; This guide shows you how to write and deploy a smart contract in Move that uses reCAPTCHA to verify users are human (and not bots) before they interact with the contract. CAPTCHA is a method of bot mitigation that requires you to pass a challenge test to prove that you are human. CAPTCHA tests are effective in preventing bots from performing tasks, but the tests can become annoying or frustrating for legitimate users if they are too difficult or frequent. reCAPTCHA is a form of CAPTCHA testing. @@ -98,7 +98,7 @@ fun init(ctx: &mut TxContext) { - The `Interaction` struct is used to define the data that is emitted as an event when a user successfully interacts with the smart contract. The `Interaction` event has two fields: the sender's address and the timestamp in milliseconds. The sender's address is the account that initiated the interaction, and the timestamp is the current time when the event is triggered. - The `Registry` struct stores the mapping of the user’s address to the expiration time of the eligibility to interact with the smart contract. It also has a `window` field that specifies the length of the time window in milliseconds. The time window is the period of time that the user is eligible to interact with the smart contract after passing the reCAPTCHA test. -- The [`init` function](concepts/iota-move-concepts/init.mdx) creates a [shared object](concepts/object-ownership/shared.mdx) for the `Registry`. The function is called when the smart contract is deployed to the blockchain. The function creates a new registry object with a unique id and sets the time window to the constant value. +- The [`init` function](../iota-101/iota-move-concepts/init.mdx) creates a [shared object](about-iota/object-ownership/shared.mdx) for the `Registry`. The function is called when the smart contract is deployed to the blockchain. The function creates a new registry object with a unique id and sets the time window to the constant value. So far, you've set up the data structures within the module. Now, create a function that verifies the message diff --git a/docs/content/guides/developer/app-examples/tic-tac-toe.mdx b/docs/content/developer/app-examples/tic-tac-toe.mdx similarity index 100% rename from docs/content/guides/developer/app-examples/tic-tac-toe.mdx rename to docs/content/developer/app-examples/tic-tac-toe.mdx diff --git a/docs/content/developer/app-examples/trustless-token-swap.mdx b/docs/content/developer/app-examples/trustless-token-swap.mdx new file mode 100644 index 00000000000..3e103f9f633 --- /dev/null +++ b/docs/content/developer/app-examples/trustless-token-swap.mdx @@ -0,0 +1,29 @@ +--- +title: Trustless Token Swap +hide_table_of_contents: true +--- + +import AppExamplesSwapSource from "../../_snippets/app-examples-swap-source.mdx"; + +This guide and example demonstrate an atomic swap on IOTA, which is similar to an escrow but does not require a trusted third party. Instead, this example uses a [shared object](../iota-101/objects/object-ownership/shared.mdx) to act as the escrow between two IOTA users wanting to trade. Shared objects are a unique concept to IOTA. Any transaction and any signer can modify it, given the changes meet the requirements set forth by the package that defined the type. + +:::info + +See [Shared versus Owned Objects](../iota-101/objects/shared-owned.mdx) for more information on the differences between object types. + +::: + +The guide is split into three parts: + +1. [Backend](trustless-token-swap/backend.mdx): The modules that hold the state and perform the swaps. +1. [Indexing and API Service](trustless-token-swap/indexer-api.mdx): A service that indexes chain state to discover trades, and an API service to read this data. +1. [Frontend](trustless-token-swap/frontend.mdx): Enables users to list objects for sale and to accept trades. + + + +## Prerequisites + +Before getting started, make sure you have: + +- [Installed the latest version of IOTA](../getting-started/iota-install.mdx). +- [Configured a valid network environment](../../references/cli/client.mdx#set-current-environment), as you will be deploying the module on Testnet. diff --git a/docs/content/guides/developer/app-examples/trustless-token-swap/backend.mdx b/docs/content/developer/app-examples/trustless-token-swap/backend.mdx similarity index 94% rename from docs/content/guides/developer/app-examples/trustless-token-swap/backend.mdx rename to docs/content/developer/app-examples/trustless-token-swap/backend.mdx index 592eaca51fe..937d7be5fa3 100644 --- a/docs/content/guides/developer/app-examples/trustless-token-swap/backend.mdx +++ b/docs/content/developer/app-examples/trustless-token-swap/backend.mdx @@ -3,9 +3,9 @@ title: Trustless Swap Backend sidebar_label: Backend --- -import InitializeIOTAClientCli from "../../../../_snippets/initialize-iota-client-cli.mdx"; -import PublishToDevnetWithCoins from "../../../../_snippets/publish-to-devnet-with-coins.mdx"; -import AppExamplesSwapSource from "../../../../_snippets/app-examples-swap-source.mdx"; +import InitializeIOTAClientCli from "../../../_snippets/initialize-iota-client-cli.mdx"; +import PublishToDevnetWithCoins from "../../../_snippets/publish-to-devnet-with-coins.mdx"; +import AppExamplesSwapSource from "../../../_snippets/app-examples-swap-source.mdx"; :::note Multi-Page Guide @@ -161,4 +161,4 @@ In conclusion, this code provides a robust and secure way to perform atomic swap You have written and deployed the Move package. To turn this into a complete dApp with frontend, you need to create a frontend. For the frontend to be updated, create an indexer that listens to the blockchain as escrows are made and swaps are fulfilled. -For the next step, you [create the indexing service](./indexer-api.mdx). +For the next step, you [create the indexing service](indexer-api.mdx). diff --git a/docs/content/guides/developer/app-examples/trustless-token-swap/frontend.mdx b/docs/content/developer/app-examples/trustless-token-swap/frontend.mdx similarity index 97% rename from docs/content/guides/developer/app-examples/trustless-token-swap/frontend.mdx rename to docs/content/developer/app-examples/trustless-token-swap/frontend.mdx index 7c65a878dee..2e8a1e68fb8 100644 --- a/docs/content/guides/developer/app-examples/trustless-token-swap/frontend.mdx +++ b/docs/content/developer/app-examples/trustless-token-swap/frontend.mdx @@ -4,7 +4,7 @@ sidebar_label: Frontend toc_max_heading_level: 2 --- -import AppExamplesSwapSource from "../../../../_snippets/app-examples-swap-source.mdx"; +import AppExamplesSwapSource from "../../../_snippets/app-examples-swap-source.mdx"; :::note Multi-Page Guide @@ -21,7 +21,7 @@ In this final part of the app example, you build a frontend (UI) that allows end Before getting started, make sure you: - Understand [the mechanism behind the Escrow smart contract backend](../trustless-token-swap.mdx). -- Check out [indexing service guide](./indexer-api.mdx) to learn how we index on-chain data and API endpoints exposed to serve data query requests. +- Check out [indexing service guide](indexer-api.mdx) to learn how we index on-chain data and API endpoints exposed to serve data query requests. - Install [`pnpm` through this guide](https://pnpm.io/installation) as we will use it as our package manager. - Check out [IOTA Typescript SDK](https://sdk.mystenlabs.com/typescript) for basic usage on how to interact with IOTA with Typescript. - Check out [IOTA dApp Kit](https://sdk.mystenlabs.com/dapp-kit) to learn basic building blocks for developing a dApp in the IOTA ecosystem with React.js. @@ -708,7 +708,7 @@ The UI has a place for users to discover, create, and execute trades. The code o ### Requested escrows -Let's take a look at the **Requested Escrows** tab by examining `src/components/escrows/EscrowList.tsx`. This time, the data is retrieved by using `useInfiniteQuery` directly from `react-query`. Fetch the data by calling the API service that you already implemented in the [Escrow Indexing and API Service Guide](./indexer-api.mdx). Call the `/escrows` endpoint to fetch all the escrows requested to you. The rationale behind using an API service to fetch the data is because the indexed data includes additional information that allows query efficiency and flexibility. You can fetch specific escrows satisfying different configured query clauses rather than limited query features of IOTA blockchain RPC endpoints. +Let's take a look at the **Requested Escrows** tab by examining `src/components/escrows/EscrowList.tsx`. This time, the data is retrieved by using `useInfiniteQuery` directly from `react-query`. Fetch the data by calling the API service that you already implemented in the [Escrow Indexing and API Service Guide](indexer-api.mdx). Call the `/escrows` endpoint to fetch all the escrows requested to you. The rationale behind using an API service to fetch the data is because the indexed data includes additional information that allows query efficiency and flexibility. You can fetch specific escrows satisfying different configured query clauses rather than limited query features of IOTA blockchain RPC endpoints. ```ts title='src/components/escrows/EscrowList.tsx' import { constructUrlSearchParams, getNextPageParam } from '@/utils/helpers'; diff --git a/docs/content/guides/developer/app-examples/trustless-token-swap/indexer-api.mdx b/docs/content/developer/app-examples/trustless-token-swap/indexer-api.mdx similarity index 99% rename from docs/content/guides/developer/app-examples/trustless-token-swap/indexer-api.mdx rename to docs/content/developer/app-examples/trustless-token-swap/indexer-api.mdx index 8817ba899e0..6f08a3a5c31 100644 --- a/docs/content/guides/developer/app-examples/trustless-token-swap/indexer-api.mdx +++ b/docs/content/developer/app-examples/trustless-token-swap/indexer-api.mdx @@ -3,7 +3,7 @@ title: Escrow Indexing and API Service sidebar_label: Indexing and API Service --- -import AppExamplesSwapSource from "../../../../_snippets/app-examples-swap-source.mdx"; +import AppExamplesSwapSource from "../../../_snippets/app-examples-swap-source.mdx"; :::note Multi-Page Guide @@ -631,4 +631,4 @@ app.get('/escrows', async (req, res) => { ## Next steps -With the code successfully deployed on Testnet, you can now [create a frontend](./frontend.mdx) to display the trading data and to allow users to interact with the Move modules. +With the code successfully deployed on Testnet, you can now [create a frontend](frontend.mdx) to display the trading data and to allow users to interact with the Move modules. diff --git a/docs/content/guides/developer/app-examples/weather-oracle.mdx b/docs/content/developer/app-examples/weather-oracle.mdx similarity index 97% rename from docs/content/guides/developer/app-examples/weather-oracle.mdx rename to docs/content/developer/app-examples/weather-oracle.mdx index 3103d250d99..6ff46fa4f50 100644 --- a/docs/content/guides/developer/app-examples/weather-oracle.mdx +++ b/docs/content/developer/app-examples/weather-oracle.mdx @@ -3,8 +3,8 @@ title: IOTA Weather Oracle description: Write a module (smart contract) in Move that fetches the weather data from the OpenWeather API every 10 minutes and updates the weather conditions for over 1,000 locations around the world. --- -import InitializeIOTAClientCli from "../../../_snippets/initialize-iota-client-cli.mdx"; -import PublishToDevnetWithCoins from "../../../_snippets/publish-to-devnet-with-coins.mdx"; +import InitializeIOTAClientCli from "../../_snippets/initialize-iota-client-cli.mdx"; +import PublishToDevnetWithCoins from "../../_snippets/publish-to-devnet-with-coins.mdx"; This guide demonstrates writing a module (smart contract) in Move, deploying it on Devnet, and adding a backend, which fetches the weather data from the OpenWeather API every 10 minutes and updates the weather conditions for each city. The dApp created in this guide is called IOTA Weather Oracle and it provides real-time weather data for over 1,000 locations around the world. @@ -102,13 +102,13 @@ fun init(otw: WEATHER, ctx: &mut TxContext) { } ``` -- The first struct, `AdminCap`, is a [capability](concepts/iota-move-concepts/patterns/capabilities.mdx). -- The second struct, `WEATHER`, is a [one-time witness](concepts/iota-move-concepts/one-time-witness.mdx) that ensures only a single instance of this `Weather` ever exists. -- The `WeatherOracle` struct works as a registry and stores the `geoname_id`s of the `CityWeatherOracle`s as [dynamic fields](concepts/dynamic-fields.mdx). -- The [`init` function](concepts/iota-move-concepts/init.mdx) creates and sends the `Publisher` and `AdminCap` objects to the sender. Also, it creates a [shared object](concepts/object-ownership/shared.mdx) for all the `CityWeatherOracle`s. +- The first struct, `AdminCap`, is a [capability](../iota-101/iota-move-concepts/patterns/capabilities.mdx). +- The second struct, `WEATHER`, is a [one-time witness](../iota-101/iota-move-concepts/one-time-witness.mdx) that ensures only a single instance of this `Weather` ever exists. +- The `WeatherOracle` struct works as a registry and stores the `geoname_id`s of the `CityWeatherOracle`s as [dynamic fields](../iota-101/objects/dynamic-fields/dynamic-fields.mdx). +- The [`init` function](../iota-101/iota-move-concepts/init.mdx) creates and sends the `Publisher` and `AdminCap` objects to the sender. Also, it creates a [shared object](../iota-101/objects/object-ownership/shared.mdx) for all the `CityWeatherOracle`s. So far, you've set up the data structures within the module. -Now, create a function that initializes a `CityWeatherOracle` and adds it as [dynamic fields](concepts/dynamic-fields.mdx) to the `WeatherOracle` object: +Now, create a function that initializes a `CityWeatherOracle` and adds it as [dynamic fields](../iota-101/objects/dynamic-fields/dynamic-fields.mdx) to the `WeatherOracle` object: ```rust title='weather.move' public fun add_city( diff --git a/docs/content/concepts/cryptography.mdx b/docs/content/developer/cryptography/explanations/cryptography.mdx similarity index 81% rename from docs/content/concepts/cryptography.mdx rename to docs/content/developer/cryptography/explanations/cryptography.mdx index f00f5fa0e7c..b7e82dbcde1 100644 --- a/docs/content/concepts/cryptography.mdx +++ b/docs/content/developer/cryptography/explanations/cryptography.mdx @@ -10,14 +10,14 @@ IOTA defines its cryptography primitives, such as public key, signature, aggrega Transaction authentication features on IOTA provide security against unauthorized access to on-chain data. Transaction Authentication provides an overview of related topics. -Go to [Transaction Authentication](./cryptography/transaction-auth.mdx). +Go to [Transaction Authentication](./transaction-auth.mdx). ## zkLogin zkLogin is a IOTA primitive that enables you to send transactions from a IOTA address using an OAuth credential, without publicly linking the two. zkLogin provides a description of the primitive and how to implement it. -Go to [zkLogin](./cryptography/zklogin.mdx). +Go to [zkLogin](./zklogin.mdx). ## Related links -- [Cryptography guides](../guides/developer/cryptography.mdx): See the cryptography guides for instruction on applying these concepts. \ No newline at end of file +- [Cryptography guides](../how-to/cryptography.mdx): See the cryptography guides for instruction on applying these concepts. \ No newline at end of file diff --git a/docs/content/concepts/cryptography/images/zklogin-apple1.png b/docs/content/developer/cryptography/explanations/images/zklogin-apple1.png similarity index 100% rename from docs/content/concepts/cryptography/images/zklogin-apple1.png rename to docs/content/developer/cryptography/explanations/images/zklogin-apple1.png diff --git a/docs/content/concepts/cryptography/images/zklogin-apple2.png b/docs/content/developer/cryptography/explanations/images/zklogin-apple2.png similarity index 100% rename from docs/content/concepts/cryptography/images/zklogin-apple2.png rename to docs/content/developer/cryptography/explanations/images/zklogin-apple2.png diff --git a/docs/content/concepts/cryptography/images/zklogin-apple3.png b/docs/content/developer/cryptography/explanations/images/zklogin-apple3.png similarity index 100% rename from docs/content/concepts/cryptography/images/zklogin-apple3.png rename to docs/content/developer/cryptography/explanations/images/zklogin-apple3.png diff --git a/docs/content/concepts/cryptography/images/zklogin-apple4.png b/docs/content/developer/cryptography/explanations/images/zklogin-apple4.png similarity index 100% rename from docs/content/concepts/cryptography/images/zklogin-apple4.png rename to docs/content/developer/cryptography/explanations/images/zklogin-apple4.png diff --git a/docs/content/concepts/cryptography/images/zklogin-facebook1.png b/docs/content/developer/cryptography/explanations/images/zklogin-facebook1.png similarity index 100% rename from docs/content/concepts/cryptography/images/zklogin-facebook1.png rename to docs/content/developer/cryptography/explanations/images/zklogin-facebook1.png diff --git a/docs/content/concepts/cryptography/images/zklogin-facebook2.png b/docs/content/developer/cryptography/explanations/images/zklogin-facebook2.png similarity index 100% rename from docs/content/concepts/cryptography/images/zklogin-facebook2.png rename to docs/content/developer/cryptography/explanations/images/zklogin-facebook2.png diff --git a/docs/content/concepts/cryptography/images/zklogin-flow.png b/docs/content/developer/cryptography/explanations/images/zklogin-flow.png similarity index 100% rename from docs/content/concepts/cryptography/images/zklogin-flow.png rename to docs/content/developer/cryptography/explanations/images/zklogin-flow.png diff --git a/docs/content/concepts/cryptography/images/zklogin-google1.png b/docs/content/developer/cryptography/explanations/images/zklogin-google1.png similarity index 100% rename from docs/content/concepts/cryptography/images/zklogin-google1.png rename to docs/content/developer/cryptography/explanations/images/zklogin-google1.png diff --git a/docs/content/concepts/cryptography/images/zklogin-google2.png b/docs/content/developer/cryptography/explanations/images/zklogin-google2.png similarity index 100% rename from docs/content/concepts/cryptography/images/zklogin-google2.png rename to docs/content/developer/cryptography/explanations/images/zklogin-google2.png diff --git a/docs/content/concepts/cryptography/images/zklogin-google3.png b/docs/content/developer/cryptography/explanations/images/zklogin-google3.png similarity index 100% rename from docs/content/concepts/cryptography/images/zklogin-google3.png rename to docs/content/developer/cryptography/explanations/images/zklogin-google3.png diff --git a/docs/content/concepts/cryptography/images/zklogin-kakao1.png b/docs/content/developer/cryptography/explanations/images/zklogin-kakao1.png similarity index 100% rename from docs/content/concepts/cryptography/images/zklogin-kakao1.png rename to docs/content/developer/cryptography/explanations/images/zklogin-kakao1.png diff --git a/docs/content/concepts/cryptography/images/zklogin-kakao2.png b/docs/content/developer/cryptography/explanations/images/zklogin-kakao2.png similarity index 100% rename from docs/content/concepts/cryptography/images/zklogin-kakao2.png rename to docs/content/developer/cryptography/explanations/images/zklogin-kakao2.png diff --git a/docs/content/concepts/cryptography/images/zklogin-kakao3.png b/docs/content/developer/cryptography/explanations/images/zklogin-kakao3.png similarity index 100% rename from docs/content/concepts/cryptography/images/zklogin-kakao3.png rename to docs/content/developer/cryptography/explanations/images/zklogin-kakao3.png diff --git a/docs/content/concepts/cryptography/images/zklogin-slack1.png b/docs/content/developer/cryptography/explanations/images/zklogin-slack1.png similarity index 100% rename from docs/content/concepts/cryptography/images/zklogin-slack1.png rename to docs/content/developer/cryptography/explanations/images/zklogin-slack1.png diff --git a/docs/content/concepts/cryptography/images/zklogin-slack2.png b/docs/content/developer/cryptography/explanations/images/zklogin-slack2.png similarity index 100% rename from docs/content/concepts/cryptography/images/zklogin-slack2.png rename to docs/content/developer/cryptography/explanations/images/zklogin-slack2.png diff --git a/docs/content/concepts/cryptography/images/zklogin-slack3.png b/docs/content/developer/cryptography/explanations/images/zklogin-slack3.png similarity index 100% rename from docs/content/concepts/cryptography/images/zklogin-slack3.png rename to docs/content/developer/cryptography/explanations/images/zklogin-slack3.png diff --git a/docs/content/concepts/cryptography/images/zklogin-twitch1.png b/docs/content/developer/cryptography/explanations/images/zklogin-twitch1.png similarity index 100% rename from docs/content/concepts/cryptography/images/zklogin-twitch1.png rename to docs/content/developer/cryptography/explanations/images/zklogin-twitch1.png diff --git a/docs/content/concepts/cryptography/images/zklogin-twitch2.png b/docs/content/developer/cryptography/explanations/images/zklogin-twitch2.png similarity index 100% rename from docs/content/concepts/cryptography/images/zklogin-twitch2.png rename to docs/content/developer/cryptography/explanations/images/zklogin-twitch2.png diff --git a/docs/content/concepts/cryptography/system/checkpoint-verification.mdx b/docs/content/developer/cryptography/explanations/system/checkpoint-verification.mdx similarity index 100% rename from docs/content/concepts/cryptography/system/checkpoint-verification.mdx rename to docs/content/developer/cryptography/explanations/system/checkpoint-verification.mdx diff --git a/docs/content/concepts/cryptography/transaction-auth.mdx b/docs/content/developer/cryptography/explanations/transaction-auth.mdx similarity index 84% rename from docs/content/concepts/cryptography/transaction-auth.mdx rename to docs/content/developer/cryptography/explanations/transaction-auth.mdx index c21d2fb3b88..6cf3c7478ad 100644 --- a/docs/content/concepts/cryptography/transaction-auth.mdx +++ b/docs/content/developer/cryptography/explanations/transaction-auth.mdx @@ -9,28 +9,28 @@ Transaction authentication features on IOTA provide security against unauthorize IOTA adheres to widely accepted wallet specifications in the cryptocurrency industry, including BIP-32 (and its variation, SLIP-0010), BIP-44, and BIP-39, to facilitate key management for users. At present, IOTA supports pure Ed25519, ECDSA Secp256k1, ECDSA Secp256r1, and multisig for signed transactions. -Go to [Keys and Addresses](./transaction-auth/keys-addresses.mdx). +Go to [Keys and Addresses](transaction-auth/keys-addresses.mdx). ## Signatures Cryptographic agility is core to IOTA. The system supports multiple cryptography algorithms and primitives and can switch between them rapidly. With IOTA, you can choose the right cryptography solution for your system and implement the latest algorithms as they become available. -Go to [Signatures](./transaction-auth/signatures.mdx). +Go to [Signatures](transaction-auth/signatures.mdx). ## Multisig IOTA supports multi-signature (multisig) transactions, which require multiple keys for authorization rather than a single, one-key signature. -Go to [Multisig](./transaction-auth/multisig.mdx). +Go to [Multisig](transaction-auth/multisig.mdx). ## Offline Signing IOTA supports offline signing, which is signing transactions using a device not connected to a IOTA network, or in a wallet implemented in a different programming language without relying on the IOTA key store. -Go to [Offline Signing](./transaction-auth/offline-signing.mdx). +Go to [Offline Signing](transaction-auth/offline-signing.mdx). ## Intent Signing In IOTA, an intent is a compact struct that serves as the domain separator for a message that a signature commits to. The data that the signature commits to is an intent message. All signatures in IOTA must commit to an intent message, instead of the message itself. -Go to [Intent Signing](./transaction-auth/intent-signing.mdx). \ No newline at end of file +Go to [Intent Signing](transaction-auth/intent-signing.mdx). \ No newline at end of file diff --git a/docs/content/concepts/cryptography/transaction-auth/images/iota_multisig_structures.png b/docs/content/developer/cryptography/explanations/transaction-auth/images/iota_multisig_structures.png similarity index 100% rename from docs/content/concepts/cryptography/transaction-auth/images/iota_multisig_structures.png rename to docs/content/developer/cryptography/explanations/transaction-auth/images/iota_multisig_structures.png diff --git a/docs/content/concepts/cryptography/transaction-auth/intent-signing.mdx b/docs/content/developer/cryptography/explanations/transaction-auth/intent-signing.mdx similarity index 98% rename from docs/content/concepts/cryptography/transaction-auth/intent-signing.mdx rename to docs/content/developer/cryptography/explanations/transaction-auth/intent-signing.mdx index e895e449a46..dedb5e8395e 100644 --- a/docs/content/concepts/cryptography/transaction-auth/intent-signing.mdx +++ b/docs/content/developer/cryptography/explanations/transaction-auth/intent-signing.mdx @@ -69,7 +69,7 @@ const signature = await this.signData(intentMessage); Under the hood, the `new_secure` method in Rust and the `signData` method in TypesScript does the following: 1. Serializes the intent message as the 3-byte intent concatenated with the BCS serialized bytes of the transaction data. 1. Applies Blake2b hash to get the 32-byte digest - 1. Passes the digest to the signing API for each corresponding scheme of the signer. The supported signature schemes are pure Ed25519, ECDSA Secp256k1 and ECDSA Secp256r1. See [IOTA Signatures](./signatures.mdx#signature-requirements) for requirements of each scheme. + 1. Passes the digest to the signing API for each corresponding scheme of the signer. The supported signature schemes are pure Ed25519, ECDSA Secp256k1 and ECDSA Secp256r1. See [IOTA Signatures](signatures.mdx#signature-requirements-signature-requirements) for requirements of each scheme. ## Authority Signature diff --git a/docs/content/concepts/cryptography/transaction-auth/keys-addresses.mdx b/docs/content/developer/cryptography/explanations/transaction-auth/keys-addresses.mdx similarity index 100% rename from docs/content/concepts/cryptography/transaction-auth/keys-addresses.mdx rename to docs/content/developer/cryptography/explanations/transaction-auth/keys-addresses.mdx diff --git a/docs/content/concepts/cryptography/transaction-auth/multisig.mdx b/docs/content/developer/cryptography/explanations/transaction-auth/multisig.mdx similarity index 97% rename from docs/content/concepts/cryptography/transaction-auth/multisig.mdx rename to docs/content/developer/cryptography/explanations/transaction-auth/multisig.mdx index a0c222316af..fd34a704d26 100644 --- a/docs/content/concepts/cryptography/transaction-auth/multisig.mdx +++ b/docs/content/developer/cryptography/explanations/transaction-auth/multisig.mdx @@ -2,7 +2,7 @@ title: Multisig --- -IOTA supports multi-signature (multisig) transactions, which require multiple keys for authorization rather than a single, one-key signature. In technical terms, IOTA supports `k` out of `n` multisig transactions, where `k` is the threshold and `n` is the total weights of all participating parties. The maximum number of parties is 10. To learn more about the single key signatures that IOTA supports, see [Signatures](./signatures.mdx). +IOTA supports multi-signature (multisig) transactions, which require multiple keys for authorization rather than a single, one-key signature. In technical terms, IOTA supports `k` out of `n` multisig transactions, where `k` is the threshold and `n` is the total weights of all participating parties. The maximum number of parties is 10. To learn more about the single key signatures that IOTA supports, see [Signatures](signatures.mdx). Valid participating keys for multisig are Pure Ed25519, ECDSA Secp256k1, and ECDSA Secp256r1. A ([u8](https://doc.rust-lang.org/std/primitive.u8.html)) weight is set for each participating keys and the threshold can be set as [u16](https://doc.rust-lang.org/std/primitive.u16.html). If the serialized multisig contains enough valid signatures of which the sum of weights passes the threshold, IOTA considers the multisig valid and the transaction executes. @@ -29,7 +29,7 @@ _Multisig structures supported in IOTA._ ## Example workflow -The following steps demonstrate how to create a multisig transaction and then submit it against a local network using the [IOTA CLI](/references/cli.mdx). A transaction can be the transfer of an object, the publish or upgrade of a package, the payment of IOTA, and so on. To learn how to set up a local network, see [Connect to a Local Network](/guides/developer/getting-started/local-network.mdx). +The following steps demonstrate how to create a multisig transaction and then submit it against a local network using the [IOTA CLI](/references/cli.mdx). A transaction can be the transfer of an object, the publish or upgrade of a package, the payment of IOTA, and so on. To learn how to set up a local network, see [Connect to a Local Network](/developer/getting-started/local-network.mdx). ### Step 1: Create keys @@ -114,7 +114,7 @@ The response resembles the following: ## Step 4: Send objects to a multisig address -This example requests gas from a local network using the default URL following the guidance in [Connect to a Local Network](/guides/developer/getting-started/local-network.mdx). If following along, be sure to replace `` with the address you receive in the previous step. +This example requests gas from a local network using the default URL following the guidance in [Connect to a Local Network](/developer/getting-started/local-network.mdx). If following along, be sure to replace `` with the address you receive in the previous step. ```shell curl --location --request POST 'http://127.0.0.1:9123/gas' --header 'Content-Type: application/json' --data-raw "{ \"FixedAmountRequest\": { \"recipient\": \"\" } }" diff --git a/docs/content/concepts/cryptography/transaction-auth/offline-signing.mdx b/docs/content/developer/cryptography/explanations/transaction-auth/offline-signing.mdx similarity index 95% rename from docs/content/concepts/cryptography/transaction-auth/offline-signing.mdx rename to docs/content/developer/cryptography/explanations/transaction-auth/offline-signing.mdx index 5077ddfca3b..113795ffeb0 100644 --- a/docs/content/concepts/cryptography/transaction-auth/offline-signing.mdx +++ b/docs/content/developer/cryptography/explanations/transaction-auth/offline-signing.mdx @@ -12,7 +12,7 @@ IOTA supports offline signing, which is signing transactions using a device not You must serialize transaction data following [Binary Canonical Serialization](https://crates.io/crates/bcs) (BCS). It is supported in other languages. -The following example demonstrates how to serialize data for a transfer using the [IOTA CLI](/references/cli.mdx). This returns serialized transaction data in Base64. Submit the raw transaction to execute as `tx_bytes`. +The following example demonstrates how to serialize data for a transfer using the [IOTA CLI](../../../../references/cli.mdx). This returns serialized transaction data in Base64. Submit the raw transaction to execute as `tx_bytes`. ```shell iota client transfer-iota --to --iota-coin-object-id --gas-budget --serialize-unsigned-transaction @@ -29,7 +29,7 @@ All other CLI commands that craft a transaction (such as `iota client publish` a ## Sign the serialized data {#sign} -You can sign the data using the device and programming language you choose. IOTA accepts signatures for pure Ed25519, ECDSA secp256k1, ECDSA secp256r1 and native multisig. To learn more about the requirements of the signatures, see [IOTA Signatures](./signatures.mdx). +You can sign the data using the device and programming language you choose. IOTA accepts signatures for pure Ed25519, ECDSA secp256k1, ECDSA secp256r1 and native multisig. To learn more about the requirements of the signatures, see [IOTA Signatures](signatures.mdx). This example uses the `iota keytool` command to sign, using the Ed25519 key corresponding to the provided address stored in `iota.keystore`. This command outputs the signature, the public key, and the flag encoded in Base64. This command is backed by fastcrypto. `iota keytool sign --address --data ` diff --git a/docs/content/concepts/cryptography/transaction-auth/signatures.mdx b/docs/content/developer/cryptography/explanations/transaction-auth/signatures.mdx similarity index 91% rename from docs/content/concepts/cryptography/transaction-auth/signatures.mdx rename to docs/content/developer/cryptography/explanations/transaction-auth/signatures.mdx index 2e49a3b4d64..249f4a92a02 100644 --- a/docs/content/concepts/cryptography/transaction-auth/signatures.mdx +++ b/docs/content/developer/cryptography/explanations/transaction-auth/signatures.mdx @@ -51,29 +51,29 @@ An accepted pure Ed25519 signature must follow: 1. The signature must be produced according to [RFC 8032](https://www.rfc-editor.org/rfc/rfc8032.html#section-5.1.6). The internal hash used is SHA-512. 1. The signature must be valid according to [ZIP215](https://github.com/zcash/zips/blob/main/zip-0215.rst). -See a concrete example for offline signing using CLI in the [Offline Signing](../transaction-auth/offline-signing.mdx) topic. +See a concrete example for offline signing using CLI in the [Offline Signing](offline-signing.mdx) topic. ## Authority signature The Authority on IOTA (collection of validators) holds three distinctive keypairs: -1. [Protocol key pair](#protocol-pair) -1. [Account key pair](#account-pair) -1. [Network key pair](#network-pair) +1. [Protocol key pair](#protocol-key-pair) +1. [Account key pair](#account-key-pair) +1. [Network key pair](#network-key-pair) -### Protocol key pair {#protocol-pair} +### Protocol key pair The protocol key pair provides authority signatures on user-signed transactions if they are verified. When a stake of the authorities that provide signatures on user transactions passes the required two-thirds threshold, IOTA executes the transaction. IOTA uses the BLS12381 scheme for its fast verification on aggregated signatures for a given number of authorities. In particular, IOTA uses the minSig BLS mode, where each individual public key is 96 bytes, while the signature is 48 bytes. The latter is important as typically validators register their keys once at the beginning of each epoch and then they continuously sign transactions; thus, we optimize on minimum signature size. As with the BLS scheme, you can aggregate independent signatures resulting in a single BLS signature payload. IOTA also accompanies the aggregated signature with a bitmap to denote which of the validators signed. This effectively reduces the authorities' signature size from (2f + 1) × `BLS_sig` size to just one `BLS_sig` payload, which in turn has significant network cost benefits resulting in compressed transaction certificates independently on the validators set size. -To counter potential rogue key attacks on BLS12381 aggregated signatures, proof of knowledge of the secret key (KOSK) is used during authority registration. When an authority requests to be added to the validator set, a proof of possession is submitted and verified. See [Intent Signing](../transaction-auth/intent-signing.mdx) on how to create a proof of possession. Unlike most standards, the IOTA proof of knowledge scheme commits to the address as well, which offers an extra protection against adversarial reuse of a validator's BLS key from another malicious validator. +To counter potential rogue key attacks on BLS12381 aggregated signatures, proof of knowledge of the secret key (KOSK) is used during authority registration. When an authority requests to be added to the validator set, a proof of possession is submitted and verified. See [Intent Signing](intent-signing.mdx) on how to create a proof of possession. Unlike most standards, the IOTA proof of knowledge scheme commits to the address as well, which offers an extra protection against adversarial reuse of a validator's BLS key from another malicious validator. -### Account key pair {#account-pair} +### Account key pair The account that the authority uses to receive payments on staking rewards is secured by the account key pair. IOTA uses pure Ed25519 as the signing scheme. -### Network key pair {#network-pair} +### Network key pair The private key is used to perform the TLS handshake required by QUIC for Narwhal primary and its worker network interface. The public key is used for validator peer ID. Pure Ed25519 is used as the signing scheme. diff --git a/docs/content/concepts/cryptography/zklogin.mdx b/docs/content/developer/cryptography/explanations/zklogin.mdx similarity index 99% rename from docs/content/concepts/cryptography/zklogin.mdx rename to docs/content/developer/cryptography/explanations/zklogin.mdx index 9d33b8c7912..dad83cc8598 100644 --- a/docs/content/concepts/cryptography/zklogin.mdx +++ b/docs/content/developer/cryptography/explanations/zklogin.mdx @@ -12,7 +12,7 @@ zkLogin is designed with the following goals in mind: - **Security:** zkLogin is a two-factor authentication scheme: sending a transaction requires both a credential from a recent OAuth login and a salt not managed by the OAuth provider. An attacker who compromises an OAuth account cannot transact from the user's corresponding IOTA address unless they separately compromise the salt. - **Privacy:** Zero-knowledge proofs prevent third parties from linking a IOTA address with its corresponding OAuth identifier. - **Optional verified identity:** A user can opt in to verify the OAuth identifier that was used to derive a particular IOTA address. This serves as the foundation for a verifiable on-chain identity layer. -- **Accessibility:** zkLogin is one of several native IOTA signature schemes thanks to IOTA's [cryptography agility](./transaction-auth/signatures.mdx). It integrates with other IOTA primitives, like sponsored transactions and multisig. +- **Accessibility:** zkLogin is one of several native IOTA signature schemes thanks to IOTA's [cryptography agility](transaction-auth/signatures.mdx). It integrates with other IOTA primitives, like sponsored transactions and multisig. - **Rigorousness:** The code for zkLogin has been independently [audited](https://github.com/iota-foundation/security-audits/blob/main/docs/zksecurity_zklogin-circuits.pdf) by two firms specializing in zero knowledge. The public zkLogin ceremony for creating the common reference string attracted contributions from more than 100 participants. Are you a builder who wants to integrate zkLogin into your application or wallet? Dive into our [Integration guide](#integration-guide). @@ -569,7 +569,7 @@ In rough sketches, the zkLogin protocol relies on the following: The address is computed on the following inputs: -1. The address flag: `zk_login_flag = 0x05` for zkLogin address. This serves as a domain separator as a signature scheme defined in [crypto agility](./transaction-auth/signatures.mdx). +1. The address flag: `zk_login_flag = 0x05` for zkLogin address. This serves as a domain separator as a signature scheme defined in [crypto agility](transaction-auth.mdx). 1. `kc_name_F = hashBytesToField(kc_name, maxKCNameLen)`: Name of the key claim, e.g., `sub`. The sequence of bytes is mapped to a field element in BN254 using `hashBytesToField` (defined below). @@ -634,7 +634,7 @@ We call the claim used to derive a users' address as the "key claim" e.g., sub o 1. `(eph_sk, eph_pk)`: Ephemeral key pair refers to the private and public key pair used to produce ephemeral signatures. The signing mechanism is the same as traditional transaction signing, but it is ephemeral because it is only stored for a short session and can be refreshed upon new OAuth sessions. The ephemeral public key is used to compute nonce. 2. `nonce`: An application-defined field embedded in the JWT token payload, computed as the hash of the ephemeral public key, JWT randomness, and the maximum epoch (IOTA's defined expiry epoch). Specifically, a zkLogin compatible nonce is required to passed in as `nonce = ToBase64URL(Poseidon_BN254([ext_eph_pk_bigint / 2^128, ext_eph_pk_bigint % 2^128, max_epoch, jwt_randomness]).to_bytes()[len - 20..])` where `ext_eph_pk_bigint` is the BigInt representation of `ext_eph_pk`. -3. `ext_eph_pk`: The byte representation of an ephemeral public key (`flag || eph_pk`). Size varies depending on the choice of the signature scheme (denoted by the flag, defined in [Signatures](./transaction-auth/signatures.mdx)). +3. `ext_eph_pk`: The byte representation of an ephemeral public key (`flag || eph_pk`). Size varies depending on the choice of the signature scheme (denoted by the flag, defined in [Signatures](transaction-auth.mdx)). 4. `user_salt`: A value introduced to unlink the OAuth identifier with the on-chain address. 5. `max_epoch`: The epoch at which the JWT token expires. This is u64 used in IOTA. 6. `kc_name`: The key claim name, e.g. `sub`. diff --git a/docs/content/concepts/cryptography/zklogin/images/overview.png b/docs/content/developer/cryptography/explanations/zklogin/images/overview.png similarity index 100% rename from docs/content/concepts/cryptography/zklogin/images/overview.png rename to docs/content/developer/cryptography/explanations/zklogin/images/overview.png diff --git a/docs/content/concepts/cryptography/zklogin/zklogin-example.mdx b/docs/content/developer/cryptography/explanations/zklogin/zklogin-example.mdx similarity index 97% rename from docs/content/concepts/cryptography/zklogin/zklogin-example.mdx rename to docs/content/developer/cryptography/explanations/zklogin/zklogin-example.mdx index f870444d60d..0c35e21b82b 100644 --- a/docs/content/concepts/cryptography/zklogin/zklogin-example.mdx +++ b/docs/content/developer/cryptography/explanations/zklogin/zklogin-example.mdx @@ -7,7 +7,7 @@ The IOTA community created an example to facilitate a comprehensive understandin - [IOTA zkLogin Example](https://iota-zklogin.vercel.app/) -![ZKLogin Overview](./images/overview.png "ZKLogin Overview") +![ZKLogin Overview](images/overview.png "ZKLogin Overview") This example breaks down the complete process of IOTA zkLogin into seven steps, as follows: 1. Generate ephemeral key pair diff --git a/docs/content/guides/developer/cryptography.mdx b/docs/content/developer/cryptography/how-to/cryptography.mdx similarity index 76% rename from docs/content/guides/developer/cryptography.mdx rename to docs/content/developer/cryptography/how-to/cryptography.mdx index 47e2e0b9a52..f6ce312800f 100644 --- a/docs/content/guides/developer/cryptography.mdx +++ b/docs/content/developer/cryptography/how-to/cryptography.mdx @@ -6,28 +6,28 @@ Effective use of cryptography keeps your smart contract transactions secure on t ## Signature verification -Move contracts in IOTA support verifications for several on-chain signature schemes. Not all signatures supported in on-chain verification are supported as user signature verification. See [Signatures](../../concepts/cryptography/transaction-auth/signatures.mdx) for valid signature schemes for transaction authorization. +Move contracts in IOTA support verifications for several on-chain signature schemes. Not all signatures supported in on-chain verification are supported as user signature verification. See [Signatures](../explanations/transaction-auth/signatures.mdx) for valid signature schemes for transaction authorization. -Go to [IOTA On-Chain Signatures Verification in Move](./cryptography/signing.mdx). +Go to [IOTA On-Chain Signatures Verification in Move](signing.mdx). ## Groth16 A zero-knowledge proof is a method by which a party, known as the prover, can confirm the truthfulness of a claim without disclosing any information about the underlying data. For instance, it's possible for the prover to demonstrate they have solved a sudoku puzzle without showing the actual solution. Groth16 is one such proof you can use in your smart contracts. -Go to [Groth16](./cryptography/groth16.mdx). +Go to [Groth16](groth16.mdx). ## Hashing A cryptographic hash function is a widely used cryptographic primitive that maps an arbitrary length input to a fixed length output, the hash value. The hash function is designed to be a one-way function, which means that it is infeasible to invert the function to find the input data from a given hash value, and to be collision resistant, which means that it is infeasible to find two different inputs that map to the same hash value. Use available hashing functions to provide security to your smart contracts. -Go to [Hashing](./cryptography/hashing.mdx). +Go to [Hashing](hashing.mdx). ## Elliptic Curve Verifiable Random Function (ECVRF) Use ECVRFs to generate a random number and provide proof that the number used a secret key for generation. The public key corresponding to the secret key verifies the proof, so you can use it as a random number generator that generates outputs that anyone can verify. Applications that need verifiable randomness on chain can also benefit from its use. -Go to [ECVRF](./cryptography/ecvrf.mdx). +Go to [ECVRF](ecvrf.mdx). ## Related links -- [Cryptography concepts](../../concepts/cryptography.mdx): Before you use the guides, you might want to learn about the concepts behind the use of cryptography on IOTA. \ No newline at end of file +- [Cryptography concepts](../explanations/cryptography.mdx): Before you use the guides, you might want to learn about the concepts behind the use of cryptography on IOTA. \ No newline at end of file diff --git a/docs/content/guides/developer/cryptography/ecvrf.mdx b/docs/content/developer/cryptography/how-to/ecvrf.mdx similarity index 100% rename from docs/content/guides/developer/cryptography/ecvrf.mdx rename to docs/content/developer/cryptography/how-to/ecvrf.mdx diff --git a/docs/content/guides/developer/cryptography/groth16.mdx b/docs/content/developer/cryptography/how-to/groth16.mdx similarity index 100% rename from docs/content/guides/developer/cryptography/groth16.mdx rename to docs/content/developer/cryptography/how-to/groth16.mdx diff --git a/docs/content/guides/developer/cryptography/hashing.mdx b/docs/content/developer/cryptography/how-to/hashing.mdx similarity index 100% rename from docs/content/guides/developer/cryptography/hashing.mdx rename to docs/content/developer/cryptography/how-to/hashing.mdx diff --git a/docs/content/guides/developer/cryptography/signing.mdx b/docs/content/developer/cryptography/how-to/signing.mdx similarity index 97% rename from docs/content/guides/developer/cryptography/signing.mdx rename to docs/content/developer/cryptography/how-to/signing.mdx index af50f69bf7b..7bac16fdf6d 100644 --- a/docs/content/guides/developer/cryptography/signing.mdx +++ b/docs/content/developer/cryptography/how-to/signing.mdx @@ -2,7 +2,7 @@ title: IOTA On-Chain Signatures Verification in Move --- -Move contracts in IOTA support verifications for several signature schemes on-chain. Not all signatures supported in on-chain verification are supported as user signature verification. See [IOTA Signatures](/concepts/cryptography/transaction-auth/signatures.mdx#user-signature) for valid signature schemes for transaction authorization. +Move contracts in IOTA support verifications for several signature schemes on-chain. Not all signatures supported in on-chain verification are supported as user signature verification. See [IOTA Signatures](../explanations/transaction-auth/signatures.mdx) for valid signature schemes for transaction authorization. This topic covers: 1. How to use [fastcrypto](https://github.com/MystenLabs/fastcrypto)'s CLI tool to create a signature of a given scheme. For testing and debugging only, DO NOT use in production. diff --git a/docs/content/guides/developer/dev-cheat-sheet.mdx b/docs/content/developer/dev-cheat-sheet.mdx similarity index 100% rename from docs/content/guides/developer/dev-cheat-sheet.mdx rename to docs/content/developer/dev-cheat-sheet.mdx diff --git a/docs/content/guides/developer.mdx b/docs/content/developer/developer.mdx similarity index 85% rename from docs/content/guides/developer.mdx rename to docs/content/developer/developer.mdx index 84bb8ac6a0b..a3865387e31 100644 --- a/docs/content/guides/developer.mdx +++ b/docs/content/developer/developer.mdx @@ -9,46 +9,46 @@ The developer guides are meant to introduce you to the Move programming language If you are completely new to Move, you should start with the aptly named Getting Started section. Topics in that section introduce you to the IOTA monorepo, guide you through installing IOTA binaries, and introduce you to some key core concepts of blockchain technology, particularly how they relate to IOTA. -Go to [Getting Started](./developer/getting-started.mdx). +Go to [Getting Started](getting-started.mdx). ## Your first dApp If you prefer to jump right in to coding (after installing IOTA, of course), then the Your First dApp is the place for you. These topics show you how to work with Move packages and get them published on-chain. -Go to [Your First IOTA dApp](./developer/first-app.mdx). +Go to [Your First IOTA dApp](getting-started/first-app/first-app.mdx). ## IOTA 101 The IOTA 101 section introduces the basics of IOTA that help you create smart contracts. These topics assume you are familiar with Move and the IOTA blockchain. -Go to [IOTA 101](./developer/iota-101.mdx). +Go to [IOTA 101](iota-101.mdx). ## Cryptography The Cryptography section demonstrates how to secure your smart contracts with cryptography to ensure authentication for access to sensitive data. -Go to [Cryptography](./developer/cryptography.mdx). +Go to [Cryptography](cryptography/how-to/cryptography.mdx). ## Advanced Topics The Advanced Topics section includes guides for advanced solutions rather than advanced users (like migrating to GraphQL or asset tokenization). These topics assume you are familiar with Move and the IOTA blockchain. -Go to [Advanced Topics](./developer/advanced.mdx). +Go to [Advanced Topics](advanced.mdx). ## App Examples The App Examples section is for anyone who learns best from reverse engineering code written by IOTA and Move experts. These examples demonstrate concepts and tasks documented throughout this site and typically include detailed explanations through code comments and specific documentation. Check back often as the available examples continue to grow. -Go to [App Examples](./developer/app-examples.mdx). +Go to [App Examples](app-examples.mdx). ## IOTA developer cheat sheet The cheat sheet collects notes from IOTA and Move developers into a single location. This document surfaces important information that might get lost in the quantity of content available. Use this often-updated page to see around corners when starting a Move project or to refresh your memory on important concepts to be mindful of. -Go to [IOTA Developer Cheat Sheet](./developer/dev-cheat-sheet.mdx). +Go to [IOTA Developer Cheat Sheet](dev-cheat-sheet.mdx). ## References If you're familiar with both Move and IOTA and just need some reference material to refresh your memory on that function you haven't used in a while, then the References section of the documentation should surface the information you need. -Go to [References](references.mdx). \ No newline at end of file +Go to [References](../references/references.mdx). \ No newline at end of file diff --git a/docs/content/guides/developer/evm-to-move.mdx b/docs/content/developer/evm-to-move.mdx similarity index 100% rename from docs/content/guides/developer/evm-to-move.mdx rename to docs/content/developer/evm-to-move.mdx diff --git a/docs/content/guides/developer/evm-to-move/creating-nft.mdx b/docs/content/developer/evm-to-move/creating-nft.mdx similarity index 99% rename from docs/content/guides/developer/evm-to-move/creating-nft.mdx rename to docs/content/developer/evm-to-move/creating-nft.mdx index 47d3bb0d4f0..c0dd39c9fca 100644 --- a/docs/content/guides/developer/evm-to-move/creating-nft.mdx +++ b/docs/content/developer/evm-to-move/creating-nft.mdx @@ -113,7 +113,7 @@ This is just a simplified NFT that anyone can mint, with just a name in it as me ### Using Object Display -The framework has a built-in feature to represent objects with templates that can be easily used for off-chain use. This allows you to save the most important data like IDs in your objects and construct, for example, a templated URL and Image URL inside a JSON object out of that without needing to host a JSON file off-chain. These templates can also be modified later if things change, making this setup much more decentralized and future-proof than using the standard `tokenURI` in an ERC-721 implementation linking to a JSON file. You can learn more about using Object Display [in the documentation](../../../standards/display.mdx). +The framework has a built-in feature to represent objects with templates that can be easily used for off-chain use. This allows you to save the most important data like IDs in your objects and construct, for example, a templated URL and Image URL inside a JSON object out of that without needing to host a JSON file off-chain. These templates can also be modified later if things change, making this setup much more decentralized and future-proof than using the standard `tokenURI` in an ERC-721 implementation linking to a JSON file. You can learn more about using Object Display [in the documentation](../standards/display.mdx). ## Differences, pitfalls, pros and cons diff --git a/docs/content/guides/developer/evm-to-move/creating-token.mdx b/docs/content/developer/evm-to-move/creating-token.mdx similarity index 95% rename from docs/content/guides/developer/evm-to-move/creating-token.mdx rename to docs/content/developer/evm-to-move/creating-token.mdx index e636588c1d3..8923441fbad 100644 --- a/docs/content/guides/developer/evm-to-move/creating-token.mdx +++ b/docs/content/developer/evm-to-move/creating-token.mdx @@ -66,7 +66,7 @@ module examples::exampletoken { There's a lot to unpack here; let's look at it piece by piece. In IOTA Move, there is no 'compiler version' defined within the module itself, like in Solidity. -A `module` is defined (`exampletoken`) as part of the `examples` package (modules always reside in packages; a package can have one or more modules in one file or spread out over several files). Within the `module,` we first alias the functionality we wish to use from other modules with `use.` If you don't do this, you would have to explicitly call other modules through their full package path, which would be very verbose and cumbersome. We import an `option` module from the `std` package and some modules from the `iota` package. The `std` and `iota` names are actually mappings as well to other modules defined in the `Move.toml` file of the package as described in the [documentation](../../../guides/developer/first-app/write-package.mdx). +A `module` is defined (`exampletoken`) as part of the `examples` package (modules always reside in packages; a package can have one or more modules in one file or spread out over several files). Within the `module,` we first alias the functionality we wish to use from other modules with `use.` If you don't do this, you would have to explicitly call other modules through their full package path, which would be very verbose and cumbersome. We import an `option` module from the `std` package and some modules from the `iota` package. The `std` and `iota` names are actually mappings as well to other modules defined in the `Move.toml` file of the package as described in the [documentation](../getting-started/first-app/write-package.mdx). After the aliases, we see an empty struct defined: @@ -74,7 +74,7 @@ After the aliases, we see an empty struct defined: struct EXAMPLETOKEN has drop {} ``` -This is the definition of the so-called [One-Time-Witness](../../../concepts/iota-move-concepts/one-time-witness.mdx). Together with the `init` function definition, this ensures that this `Coin` will only be created once and never more on this chain. +This is the definition of the so-called [One-Time-Witness](../iota-101/iota-move-concepts/one-time-witness.mdx). Together with the `init` function definition, this ensures that this `Coin` will only be created once and never more on this chain. The `init` function is called automatically when a package is published for every module. The One-Time-Witness and a `TxContext` object containing more information about the function call itself, like the address deploying the package (sender), are passed automatically. @@ -86,7 +86,7 @@ After publishing this package, the `init` functionality is called, and we now ha ./iota client call --function mint_and_transfer --module coin --package 0x...... --args 0x...... 5 "0x...receiver..." --type-args $0x......::exampletoken::EXAMPLETOKEN --gas-budget 10000 ``` -An important thing to note here is that unlike with ERC-20, a `Coin` has some properties that hold true for every `Coin` type, including the ability to freely transfer `Coin` objects without limitation (except [Regulated Coins](../../../standards/coin.mdx#regulated-coins) which can block transfers on a per-address base). You can't simply add limiting logic to your module like you can with an ERC-20 contract. Still, you would need to wrap the `Coin` in another module that does hold these constraints to implement this logic. +An important thing to note here is that unlike with ERC-20, a `Coin` has some properties that hold true for every `Coin` type, including the ability to freely transfer `Coin` objects without limitation (except [Regulated Coins](../standards/coin.mdx#regulated-coins) which can block transfers on a per-address base). You can't simply add limiting logic to your module like you can with an ERC-20 contract. Still, you would need to wrap the `Coin` in another module that does hold these constraints to implement this logic. ### Using `CoinManager` @@ -127,7 +127,7 @@ fun init(witness: EXAMPLETOKEN, ctx: &mut TxContext) { ### Using Closed-Loop tokens -While the `CoinManager` can limit and expand upon the management capabilities of a `Coin` type, the same rules for using a `Coin` still apply: unrestricted freedom to transfer tokens. If you need to limit this, you can either wrap the `Coin` instances in another object that adds limitations, or you can use the Closed-Loop `Token` standard, which does this in a comprehensive and standardized way. You can read more about how Closed-Loop tokens work in [the documentation](../../../standards/closed-loop-token.mdx). +While the `CoinManager` can limit and expand upon the management capabilities of a `Coin` type, the same rules for using a `Coin` still apply: unrestricted freedom to transfer tokens. If you need to limit this, you can either wrap the `Coin` instances in another object that adds limitations, or you can use the Closed-Loop `Token` standard, which does this in a comprehensive and standardized way. You can read more about how Closed-Loop tokens work in [the documentation](../standards/closed-loop-token.mdx). ## Differences, pitfalls, pros and cons diff --git a/docs/content/guides/developer/evm-to-move/tooling-apis.mdx b/docs/content/developer/evm-to-move/tooling-apis.mdx similarity index 91% rename from docs/content/guides/developer/evm-to-move/tooling-apis.mdx rename to docs/content/developer/evm-to-move/tooling-apis.mdx index dc9efe07be4..4b70fd63da3 100644 --- a/docs/content/guides/developer/evm-to-move/tooling-apis.mdx +++ b/docs/content/developer/evm-to-move/tooling-apis.mdx @@ -34,7 +34,7 @@ Unlike with EVM, where open-source third parties create the most used tooling, t ### SDKs -IOTA Move comes with a convenient [Rust](../../../references/rust-sdk.mdx) and TypeScript{/*TODO: add-link-to-ts-docs-once-merged-in*/} SDK right out of the box as part of the IOTA Move core. Next to that, a dApp toolkit is also offered by default, which provides several React components to more easily integrate your IOTA Move contract interaction within your dApp. If desired, an unofficial Go SDK{/*TODO: Add-link-to-go-sdk-repo*/} can be used. While TypeScript covers most dApp requirements for an SDK, there might not be an SDK available for your language of choice at the moment. However, You can use one of the APIs directly on a lower level. +IOTA Move comes with a convenient [Rust](../../references/rust-sdk.mdx) and TypeScript{/*TODO: add-link-to-ts-docs-once-merged-in*/} SDK right out of the box as part of the IOTA Move core. Next to that, a dApp toolkit is also offered by default, which provides several React components to more easily integrate your IOTA Move contract interaction within your dApp. If desired, an unofficial Go SDK{/*TODO: Add-link-to-go-sdk-repo*/} can be used. While TypeScript covers most dApp requirements for an SDK, there might not be an SDK available for your language of choice at the moment. However, You can use one of the APIs directly on a lower level. ### Wallets diff --git a/docs/content/guides/developer/evm-to-move/why-move.mdx b/docs/content/developer/evm-to-move/why-move.mdx similarity index 100% rename from docs/content/guides/developer/evm-to-move/why-move.mdx rename to docs/content/developer/evm-to-move/why-move.mdx diff --git a/docs/content/guides/operator/exchange-integration.mdx b/docs/content/developer/exchange-integration/exchange-integration.mdx similarity index 97% rename from docs/content/guides/operator/exchange-integration.mdx rename to docs/content/developer/exchange-integration/exchange-integration.mdx index d02a5edc1ab..51559d72b0c 100644 --- a/docs/content/guides/operator/exchange-integration.mdx +++ b/docs/content/developer/exchange-integration/exchange-integration.mdx @@ -18,7 +18,7 @@ For best results, run IOTA Full nodes on Linux. IOTA supports the Ubuntu and Deb ## Configure a IOTA Full node -You can set up and configure a [IOTA Full node](./iota-full-node.mdx) using Docker or directly from source code in the IOTA GitHub repository. +You can set up and configure a [IOTA Full node](../../operator/iota-full-node.mdx) using Docker or directly from source code in the IOTA GitHub repository. ## Set up IOTA addresses @@ -172,7 +172,7 @@ IOTA supports the following API operations related to transferring IOTA between ## Signing transactions -Refer to [IOTA Signatures](/concepts/cryptography/transaction-auth/signatures.mdx) for more details on signature validity requirements. +Refer to [IOTA Signatures](../cryptography/explanations/transaction-auth/signatures.mdx) for more details on signature validity requirements. ## IOTA Staking diff --git a/docs/content/guides/stardust-migration.mdx b/docs/content/developer/exchange-integration/stardust-migration.mdx similarity index 100% rename from docs/content/guides/stardust-migration.mdx rename to docs/content/developer/exchange-integration/stardust-migration.mdx diff --git a/docs/content/developer/getting-started.mdx b/docs/content/developer/getting-started.mdx new file mode 100644 index 00000000000..592d407000a --- /dev/null +++ b/docs/content/developer/getting-started.mdx @@ -0,0 +1,34 @@ +--- +title: Getting Started +--- + +IOTA is the first internet-scale programmable blockchain platform. That might read like marketing speak, but as you peruse the documentation to understand the technology, you will discover that IOTA addresses many of the problems that hold blockchains back from mass adoption. + +Before you can get started developing on IOTA, you need to understand the code repository and install its binaries. Consequently, the first two topics you need are: + +- [IOTA Environment Setup](getting-started/iota-environment.mdx) +- [Install IOTA](getting-started/iota-install.mdx) + +## After installing IOTA + +After you have IOTA installed on your system, you can begin to connect with a network and publish smart contracts. + +- [Connect to a IOTA Network](getting-started/connect.mdx) +- [Connect to a Local Network](getting-started/local-network.mdx) +- [Get IOTA Address](getting-started/get-address.mdx) +- [Get IOTA Coins](getting-started/get-coins.mdx) + +## GraphQL queries + +Use the GraphQL service for IOTA RPC to interact with on-chain data. + +Go to [Query IOTA RPC with GraphQL](getting-started/graphql-rpc.mdx). + +## Related links + +After installing IOTA and setting up your development environment, use the information in the following sections to continue your development journey. + +- [App Examples](app-examples.mdx): A mix of end-to-end examples that you can draw inspiration from in your own projects. +- [IOTA 101](iota-101.mdx): Topics that you should know when just starting out to develop on IOTA. +- [Advanced Topics](advanced.mdx): Topics that you might not find beneficial until you start solving more complex problems. +- [Cryptography](cryptography/how-to/cryptography.mdx): Leverage cryptography functions to provide security for your smart contract actions. diff --git a/docs/content/guides/developer/getting-started/connect.mdx b/docs/content/developer/getting-started/connect.mdx similarity index 86% rename from docs/content/guides/developer/getting-started/connect.mdx rename to docs/content/developer/getting-started/connect.mdx index 986b1fc77c3..0368b96be09 100644 --- a/docs/content/guides/developer/getting-started/connect.mdx +++ b/docs/content/developer/getting-started/connect.mdx @@ -3,13 +3,13 @@ title: Connect to a IOTA Network description: Besides Mainnet, IOTA offers Testnet, Devnet, and local networks that you can connect to for development. You can also configure a custom RPC endpoint. --- -import DataWipe from "../../../_snippets/data-wipe.mdx"; +import DataWipe from "../../_snippets/data-wipe.mdx"; -IOTA has Mainnet, Devnet, and Testnet networks available. You can use one of the test networks, Devnet or Testnet, to experiment with the version of IOTA running on that network. You can also spin up a [local IOTA network](./local-network.mdx) for local development. +IOTA has Mainnet, Devnet, and Testnet networks available. You can use one of the test networks, Devnet or Testnet, to experiment with the version of IOTA running on that network. You can also spin up a [local IOTA network](local-network.mdx) for local development. The IOTA Testnet and Devnet networks consist of four validator nodes operated by Mysten Labs. Clients send transactions and read requests via this endpoint: `https://fullnode..iota.io:443` using [JSON-RPC](/references/iota-api/json-rpc-format.mdx). -You can [request test IOTA tokens](#request-test-tokens) through the IOTA [devnet-faucet](https://discordapp.com/channels/916379725201563759/971488439931392130) and [testnet-faucet](https://discord.com/channels/916379725201563759/1037811694564560966) Discord channels, depending on which version of the network you use. If connected to Localnet, use cURL to request tokens from your [local faucet](./local-network.mdx#use-the-local-faucet). The coins on these networks have no financial value. There is no faucet service for Mainnet. +You can [request test IOTA tokens](#request-test-tokens) through the IOTA [devnet-faucet](https://discordapp.com/channels/916379725201563759/971488439931392130) and [testnet-faucet](https://discord.com/channels/916379725201563759/1037811694564560966) Discord channels, depending on which version of the network you use. If connected to Localnet, use cURL to request tokens from your [local faucet](local-network.mdx#use-the-local-faucet). The coins on these networks have no financial value. There is no faucet service for Mainnet. See announcements about IOTA in the [#announcements](https://discord.com/channels/916379725201563759/925109817834631189) Discord channel. @@ -28,7 +28,7 @@ IOTA provides [IOTA command line interface (CLI)](/references/cli/client.mdx) to ## Environment set up -First, [Install IOTA](./iota-install.mdx#install-binaries). After you install IOTA, [request IOTA test tokens](#request-gas-tokens) through Discord for the network you are using: [Devnet](https://discordapp.com/channels/916379725201563759/971488439931392130) or [Testnet](https://discord.com/channels/916379725201563759/1037811694564560966). If connected to Localnet, use cURL to request tokens from your [local faucet](./local-network.mdx#use-the-local-faucet). +First, [Install IOTA](iota-install.mdx#install-binaries). After you install IOTA, [request IOTA test tokens](#request-gas-tokens) through Discord for the network you are using: [Devnet](https://discordapp.com/channels/916379725201563759/971488439931392130) or [Testnet](https://discord.com/channels/916379725201563759/1037811694564560966). If connected to Localnet, use cURL to request tokens from your [local faucet](local-network.mdx#use-the-local-faucet). To check whether IOTA is already installed, run the following command: @@ -116,4 +116,4 @@ To switch the active network, run the following command: iota client switch --env ``` -If you encounter an issue, delete the IOTA configuration directory (`~/.iota/iota_config`) and reinstall the latest [IOTA binaries](./iota-install.mdx#install-iota-binaries). +If you encounter an issue, delete the IOTA configuration directory (`~/.iota/iota_config`) and reinstall the latest [IOTA binaries](iota-install.mdx#install-iota-binaries). diff --git a/docs/content/guides/developer/first-app/build-test.mdx b/docs/content/developer/getting-started/first-app/build-test.mdx similarity index 95% rename from docs/content/guides/developer/first-app/build-test.mdx rename to docs/content/developer/getting-started/first-app/build-test.mdx index e8f17be128b..c2b5896f5e8 100644 --- a/docs/content/guides/developer/first-app/build-test.mdx +++ b/docs/content/developer/getting-started/first-app/build-test.mdx @@ -2,7 +2,7 @@ title: Build and Test Packages --- -If you followed [Write a Move Package](./write-package.mdx), you have a basic module that you need to build. If you didn't, then either start with that topic or use your package, substituting that information where appropriate. +If you followed [Write a Move Package](write-package.mdx), you have a basic module that you need to build. If you didn't, then either start with that topic or use your package, substituting that information where appropriate. ## Building your package @@ -35,7 +35,7 @@ An individual Move unit test is encapsulated in a public function that has no pa $ iota move test ``` -If you execute this command for the package created in [Write a Package](./write-package.mdx), you see the following output. Unsurprisingly, the test result has an `OK` status because there are no tests written yet to fail. +If you execute this command for the package created in [Write a Package](write-package.mdx), you see the following output. Unsurprisingly, the test result has an `OK` status because there are no tests written yet to fail. ```shell BUILDING IOTA @@ -244,7 +244,7 @@ Transaction effects, such as object creation and transfer become visible only af ::: -The final owner executes the fourth and final transaction that retrieves the `sword` object from storage and checks if it has the expected properties. Remember, as described in [Testing a package](#testing-a-package), in the pure Move testing scenario, after an object is available in Move code (after creation or retrieval from emulated storage), it cannot simply disappear. +The final owner executes the fourth and final transaction that retrieves the `sword` object from storage and checks if it has the expected properties. Remember, as described in [Testing a package](#testing-a-package-testing-a-package), in the pure Move testing scenario, after an object is available in Move code (after creation or retrieval from emulated storage), it cannot simply disappear. In the pure Move testing function, the function transfers the `sword` object to the fake address to handle the disappearing problem. The `test_scenario` package provides a more elegant solution, however, which is closer to what happens when Move code actually executes in the context of IOTA - the package simply returns the `sword` to the object pool using the `test_scenario::return_to_sender` function. For scenarios where returning to the sender is not desirable or if you would like to simply destroy the object, the `test_utils` module also provides the generic `destroy` function, that can be used on any type `T` regardless of its ability. It is advisable to check out other useful functions in the [`test_scenario`](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/packages/iota-framework/sources/test/test_scenario.move) and [`test_utils`](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/packages/iota-framework/sources/test/test_utils.move) modules as well. @@ -355,5 +355,5 @@ You can refer to the source code for the package (with all the tests and functio ## Related links -- [Publish a Package](./publish.mdx): Continue the example by publishing your package to the IOTA network. -- [Package Upgrades](../../../concepts/iota-move-concepts/packages.mdx): Upgrading packages published on the IOTA network. +- [Publish a Package](publish.mdx): Continue the example by publishing your package to the IOTA network. +- [Package Upgrades](../../iota-101/iota-move-concepts/packages/packages.mdx): Upgrading packages published on the IOTA network. diff --git a/docs/content/guides/developer/first-app/client-tssdk.mdx b/docs/content/developer/getting-started/first-app/client-tssdk.mdx similarity index 96% rename from docs/content/guides/developer/first-app/client-tssdk.mdx rename to docs/content/developer/getting-started/first-app/client-tssdk.mdx index 4c2071be5e8..6af7bd83ab5 100644 --- a/docs/content/guides/developer/first-app/client-tssdk.mdx +++ b/docs/content/developer/getting-started/first-app/client-tssdk.mdx @@ -218,6 +218,6 @@ You now have a dApp connected to wallets and can query data from RPC nodes. The next step from here is to start interacting with Move modules, constructing transaction blocks, and making Move calls. This exercise continues in the Counter end-to-end example. -- [End-to-End Example](../app-examples/e2e-counter.mdx): Continue this exercise by creating an app. -- [IOTA 101](../iota-101.mdx): Learn the basics of the IOTA network and how to interact with on-chain objects using Move. +- [End-to-End Example](../../app-examples/e2e-counter.mdx): Continue this exercise by creating an app. +- [IOTA 101](../../iota-101.mdx): Learn the basics of the IOTA network and how to interact with on-chain objects using Move. - [IOTA Move CLI](/references/cli/move.mdx): The `move` commands in the IOTA CLI provide console or terminal interaction with the Move VM. diff --git a/docs/content/guides/developer/first-app/debug.mdx b/docs/content/developer/getting-started/first-app/debug.mdx similarity index 97% rename from docs/content/guides/developer/first-app/debug.mdx rename to docs/content/developer/getting-started/first-app/debug.mdx index e15bee4d37b..ee72b1b4a7a 100644 --- a/docs/content/guides/developer/first-app/debug.mdx +++ b/docs/content/developer/getting-started/first-app/debug.mdx @@ -109,4 +109,4 @@ Test result: OK. Total tests: 2; passed: 2; failed: 0 ## Related links -- [Publish a Package](./publish.mdx): Publish the example to the IOTA network. \ No newline at end of file +- [Publish a Package](publish.mdx): Publish the example to the IOTA network. \ No newline at end of file diff --git a/docs/content/guides/developer/first-app.mdx b/docs/content/developer/getting-started/first-app/first-app.mdx similarity index 84% rename from docs/content/guides/developer/first-app.mdx rename to docs/content/developer/getting-started/first-app/first-app.mdx index da4341d52e7..01c44be16dd 100644 --- a/docs/content/guides/developer/first-app.mdx +++ b/docs/content/developer/getting-started/first-app/first-app.mdx @@ -3,7 +3,7 @@ title: Your First IOTA dApp description: Build your first dApp and publish it on chain. These guides demonstrate the basics you need to know to start your development journey on IOTA. --- -Before you can create your first dApp, you must have [IOTA installed](./getting-started/iota-install.mdx). +Before you can create your first dApp, you must have [IOTA installed](../iota-install.mdx). You use Move to write packages that live on chain, meaning they exist on the IOTA network you publish them to. The instructions in this section walk you through writing a basic package, debugging and testing your code, and publishing. You need to follow these instructions in order to complete the exercise. @@ -49,8 +49,8 @@ You are now connected to the IOTA Testnet network and should have an account wit ## Related links -- [Write a Move Package](./first-app/write-package.mdx): Continue this example by creating the necessary Move code for your package. -- [Connect to a IOTA Network](./getting-started/connect.mdx): Connect to an available IOTA network. -- [Connect to a Local Network](./getting-started/local-network.mdx): Start and connect to a local IOTA network. -- [Get IOTA Address](./getting-started/get-address.mdx): Get an address for the current IOTA network. -- [Get IOTA Tokens](./getting-started/get-coins.mdx): Get IOTA for the active address on Devnet, Testnet, or a local network. \ No newline at end of file +- [Write a Move Package](write-package.mdx): Continue this example by creating the necessary Move code for your package. +- [Connect to a IOTA Network](../connect.mdx): Connect to an available IOTA network. +- [Connect to a Local Network](../local-network.mdx): Start and connect to a local IOTA network. +- [Get IOTA Address](../get-address.mdx): Get an address for the current IOTA network. +- [Get IOTA Tokens](../get-coins.mdx): Get IOTA for the active address on Devnet, Testnet, or a local network. \ No newline at end of file diff --git a/docs/content/guides/developer/first-app/publish.mdx b/docs/content/developer/getting-started/first-app/publish.mdx similarity index 95% rename from docs/content/guides/developer/first-app/publish.mdx rename to docs/content/developer/getting-started/first-app/publish.mdx index 5c0b02a7eb5..016e4fcb9e6 100644 --- a/docs/content/guides/developer/first-app/publish.mdx +++ b/docs/content/developer/getting-started/first-app/publish.mdx @@ -82,7 +82,7 @@ flowchart TB ### Interact with the package -Now that the package is on chain, you can call its functions to interact with the package. You can use the `iota move call` command to make individual calls to package functions, or you can construct more advanced blocks of transactions using the `iota client ptb` command. The `ptb` part of the command stands for [programmable transaction blocks](../../../concepts/transactions/prog-txn-blocks.mdx). In basic terms, PTBs allow you to group commands together in a single transaction for more efficient and cost-effective network activity. +Now that the package is on chain, you can call its functions to interact with the package. You can use the `iota move call` command to make individual calls to package functions, or you can construct more advanced blocks of transactions using the `iota client ptb` command. The `ptb` part of the command stands for [programmable transaction blocks](../../iota-101/transactions/ptb/prog-txn-blocks.mdx). In basic terms, PTBs allow you to group commands together in a single transaction for more efficient and cost-effective network activity. ```mermaid flowchart TB @@ -112,6 +112,7 @@ $ iota client ptb \ :::info + ::: @@ -153,9 +154,9 @@ Congratulations! You have successfully published a package to the IOTA network a ## Related links -- [Debugging](./debug.mdx): Print values to aid in logic debugging. -- [Package Upgrades](../../../concepts/iota-move-concepts/packages.mdx): Upgrading packages published on the IOTA network. +- [Debugging](debug.mdx): Print values to aid in logic debugging. +- [Package Upgrades](../../iota-101/iota-move-concepts/packages/packages.mdx): Upgrading packages published on the IOTA network. - [Publish a Move Package](../../../references/cli/client.mdx#publish-a-move-package): More details about using the CLI to publish a package. -- [Programmable Transaction Blocks](../../../concepts/transactions/prog-txn-blocks.mdx): PTBs are collections of transactions that are executed together. +- [Programmable Transaction Blocks](../../iota-101/transactions/ptb/prog-txn-blocks.mdx): PTBs are collections of transactions that are executed together. - [IOTA Client PTB CLI](../../../references/cli/ptb.mdx): The `client ptb` command allows you to specify the transactions for execution in a programmable transaction block directly from your CLI or through bash scripts. -- [App Examples](../app-examples.mdx): End-to-end examples that include smart contract logic and frontend code. +- [App Examples](../../app-examples.mdx): End-to-end examples that include smart contract logic and frontend code. diff --git a/docs/content/guides/developer/first-app/write-package.mdx b/docs/content/developer/getting-started/first-app/write-package.mdx similarity index 98% rename from docs/content/guides/developer/first-app/write-package.mdx rename to docs/content/developer/getting-started/first-app/write-package.mdx index 373a07d7333..63c143e1669 100644 --- a/docs/content/guides/developer/first-app/write-package.mdx +++ b/docs/content/developer/getting-started/first-app/write-package.mdx @@ -133,5 +133,5 @@ After you save the file, you have a complete Move package. ## Related links -- [Build and Test Packages](./build-test.mdx): Continue this example to build and test your package to get it ready for publishing. +- [Build and Test Packages](build-test.mdx): Continue this example to build and test your package to get it ready for publishing. - [IOTA Move CLI](../../../references/cli/move.mdx): Available Move commands the CLI provides. \ No newline at end of file diff --git a/docs/content/guides/developer/getting-started/get-address.mdx b/docs/content/developer/getting-started/get-address.mdx similarity index 91% rename from docs/content/guides/developer/getting-started/get-address.mdx rename to docs/content/developer/getting-started/get-address.mdx index 7a2e6c6e7ad..0ee6e454064 100644 --- a/docs/content/guides/developer/getting-started/get-address.mdx +++ b/docs/content/developer/getting-started/get-address.mdx @@ -9,7 +9,7 @@ The IOTA address is unique, similarly to the way a social security number or a p In IOTA, an address is 32 bytes and is often encoded in base58 with `0x` prefix. For example, this is a valid IOTA address: `0x02a212de6a9dfa3a69e22387acfbafbb1a9e591bd9d636e7895dcfc8de05f331`. You can use the a IOTA network explorer to find more information about this address and the objects it owns. -If you'd like to understand how a IOTA address is derived from private keys and other cryptography related topics, see the [Keys and Addresses](/concepts/cryptography/transaction-auth/keys-addresses.mdx) topic. +If you'd like to understand how a IOTA address is derived from private keys and other cryptography related topics, see the [Keys and Addresses](../cryptography/explanations/transaction-auth/keys-addresses.mdx) topic. ## How to obtain a IOTA address @@ -33,9 +33,9 @@ If you are using the IOTA command line interface (CLI) to interact with the IOTA To generate a new IOTA address use `iota client new-address ed25519`, which specifies the keypair scheme flag to be of type `ed25519`. -For more information, see the [IOTA Client CLI](../../../references/cli/client.mdx) documentation. +For more information, see the [IOTA Client CLI](../../references/cli/client.mdx) documentation. -To see all the generated addresses in the local wallet on your machine, run `iota keytool list`. For more information about the keytool options, see the [IOTA Keytool CLI](../../../references/cli/keytool.mdx) documentation. +To see all the generated addresses in the local wallet on your machine, run `iota keytool list`. For more information about the keytool options, see the [IOTA Keytool CLI](../../references/cli/keytool.mdx) documentation. :::danger diff --git a/docs/content/guides/developer/getting-started/get-coins.mdx b/docs/content/developer/getting-started/get-coins.mdx similarity index 80% rename from docs/content/guides/developer/getting-started/get-coins.mdx rename to docs/content/developer/getting-started/get-coins.mdx index 06d0e084e95..35b431887ca 100644 --- a/docs/content/guides/developer/getting-started/get-coins.mdx +++ b/docs/content/developer/getting-started/get-coins.mdx @@ -6,10 +6,10 @@ IOTA faucet is a helpful tool where IOTA developers can get free test IOTA token ## Prerequisites -To request tokens from the faucet, you must own a wallet address that can receive the IOTA tokens. See the [Get IOTA Address](./get-address.mdx) topic if you don't already have an address or need to create a new one. +To request tokens from the faucet, you must own a wallet address that can receive the IOTA tokens. See the [Get IOTA Address](get-address.mdx) topic if you don't already have an address or need to create a new one. ## Request test tokens via the CLI -If you are using the Devnet or Testnet networks, or you spun up a local network, you can use the [IOTA CLI](../../../references/cli/client.mdx) to request tokens for your address. The `iota client faucet` uses the active network and active address that is currently set in the IOTA CLI by default, but you can specify custom data through the following two arguments: +If you are using the Devnet or Testnet networks, or you spun up a local network, you can use the [IOTA CLI](../../references/cli/client.mdx) to request tokens for your address. The `iota client faucet` uses the active network and active address that is currently set in the IOTA CLI by default, but you can specify custom data through the following two arguments: - `--address` argument to provide a specific address (or its alias), - `--url` argument to provide a custom faucet endpoint. @@ -60,4 +60,4 @@ await requestIOTAFromFaucetV0({ ## Test tokens on a local network -If you are running a local IOTA network, you can get tokens from your local faucet. See the [Connect to a Local Network](./local-network.mdx#use-the-local-faucet) topic for details. +If you are running a local IOTA network, you can get tokens from your local faucet. See the [Connect to a Local Network](local-network.mdx#use-the-local-faucet) topic for details. diff --git a/docs/content/guides/developer/getting-started/graphql-rpc.mdx b/docs/content/developer/getting-started/graphql-rpc.mdx similarity index 83% rename from docs/content/guides/developer/getting-started/graphql-rpc.mdx rename to docs/content/developer/getting-started/graphql-rpc.mdx index 881e1e54947..07cb1361229 100644 --- a/docs/content/guides/developer/getting-started/graphql-rpc.mdx +++ b/docs/content/developer/getting-started/graphql-rpc.mdx @@ -12,7 +12,7 @@ The online IDE is available for [Mainnet](https://iota-mainnet.mystenlabs.com/gr - Both [mainnet](https://iota-mainnet.mystenlabs.com/graphql) and [testnet](https://iota-testnet.mystenlabs.com/graphql) services are rate-limited to keep network throughput optimized. ::: -For more details about some concepts used in the examples below, please see the [GraphQL concepts](../../../concepts/graphql-rpc.mdx) page, and consult the [reference](../../../references/iota-graphql.mdx) for full documentation on the supported schema. +For more details about some concepts used in the examples below, please see the [GraphQL concepts](../graphql-rpc.mdx) page, and consult the [reference](../../references/iota-graphql.mdx) for full documentation on the supported schema. ## Discovering the schema @@ -102,7 +102,7 @@ query { This example finds all the transactions that touched (modified/transferred/deleted) a given object. This is useful for when we want to trace the flow of a Coin/StakeIOTA/NFT. :::info -This example uses GraphQL [variables](../../../concepts/graphql-rpc.mdx#variables) and [pagination](../../../concepts/graphql-rpc.mdx#pagination). When using the online IDE, copy the variables JSON to the "Variables" window, below the main editor. +This example uses GraphQL [variables](../graphql-rpc.mdx#variables) and [pagination](../graphql-rpc.mdx#pagination). When using the online IDE, copy the variables JSON to the "Variables" window, below the main editor. ::: ```graphql @@ -190,7 +190,7 @@ query ($address: IOTAAddress!) { ## Fetching a dynamic field on an object :::info -This example uses aliases and [fragments](../../../concepts/graphql-rpc.mdx#fragments). +This example uses aliases and [fragments](../graphql-rpc.mdx#fragments). ::: ```graphql @@ -242,10 +242,10 @@ fragment MoveValueFields on MoveValue { ## Fetching all dynamic fields on an object -This query can be used to paginate over the dynamic fields of an object. This works even when the object in question is [wrapped](../../../concepts/object-ownership/wrapped.mdx), by using the owner query, so can be used for iterating over the elements of on-chain data structures, like [Tables and Bags](../../../concepts/dynamic-fields/tables-bags.mdx). +This query can be used to paginate over the dynamic fields of an object. This works even when the object in question is [wrapped](../iota-101/objects/object-ownership/wrapped.mdx), by using the owner query, so can be used for iterating over the elements of on-chain data structures, like [Tables and Bags](../iota-101/objects/dynamic-fields/tables-bags.mdx). :::info -This example uses [fragments](../../../concepts/graphql-rpc.mdx#fragments) and [variables](../../../concepts/graphql-rpc.mdx#variables). +This example uses [fragments](../graphql-rpc.mdx#fragments) and [variables](../graphql-rpc.mdx#variables). ::: ```graphql @@ -299,7 +299,7 @@ Sets up a paginated query, starting at the genesis checkpoint, reading five chec :::info -This example uses GraphQL [variables](../../../concepts/graphql-rpc.mdx#variables) and [pagination](../../../concepts/graphql-rpc.mdx#pagination). +This example uses GraphQL [variables](../graphql-rpc.mdx#variables) and [pagination](../graphql-rpc.mdx#pagination). ::: @@ -323,12 +323,12 @@ query ($before: String) { Sets up a paginated query, starting at the latest indexed checkpoint, reading five checkpoints at a time, in decreasing order of sequence number. The value of `pageInfo.hasPreviousPage` determines whether there is another page to be read, and the value of `pageInfo.startCursor` is fed back in as the cursor to read `$before`. :::info -This example uses GraphQL [variables](../../../concepts/graphql-rpc.mdx#variables) and [pagination](../../../concepts/graphql-rpc.mdx#pagination). +This example uses GraphQL [variables](../graphql-rpc.mdx#variables) and [pagination](../graphql-rpc.mdx#pagination). ::: ## Executing a transaction -Transaction execution takes in two arguments, `txBytes` and `signatures`. `txBytes` is the serialized unsigned transaction data, which can be generated when using the IOTA CLI's `client call` [command](../../../references/cli/client.mdx), to call a Move function by passing the `--serialize-unsigned-transaction` flag. The `signatures` can be generated using IOTA CLI's [keytool](../../../references/cli/keytool.mdx) command `iota keytool sign`. More information on IOTA CLI can be found [here](/references/cli). +Transaction execution takes in two arguments, `txBytes` and `signatures`. `txBytes` is the serialized unsigned transaction data, which can be generated when using the IOTA CLI's `client call` [command](../../references/cli/client.mdx), to call a Move function by passing the `--serialize-unsigned-transaction` flag. The `signatures` can be generated using IOTA CLI's [keytool](../../references/cli/keytool.mdx) command `iota keytool sign`. More information on IOTA CLI can be found [here](../../references/cli). ```graphql mutation ($tx: String!, $sigs: [String!]!) { @@ -370,5 +370,5 @@ Examples in the repository are designed to work with the version of GraphQL buil ## Related links - [GraphQL migration](../advanced/graphql-migration.mdx): Migrating to GraphQL guides you through migrating IOTA RPC projects from JSON-RPC to GraphQL. -- [GraphQL concepts](../../../concepts/graphql-rpc.mdx): GraphQL for IOTA RPC examines the elements of GraphQL that you should know to get the most from the service. -- [GraphQL reference](../../../references/iota-graphql.mdx): Auto-generated GraphQL reference for IOTA RPC. \ No newline at end of file +- [GraphQL concepts](../graphql-rpc.mdx): GraphQL for IOTA RPC examines the elements of GraphQL that you should know to get the most from the service. +- [GraphQL reference](../../references/iota-graphql.mdx): Auto-generated GraphQL reference for IOTA RPC. \ No newline at end of file diff --git a/docs/content/guides/developer/getting-started/images/fork.png b/docs/content/developer/getting-started/images/fork.png similarity index 100% rename from docs/content/guides/developer/getting-started/images/fork.png rename to docs/content/developer/getting-started/images/fork.png diff --git a/docs/content/guides/developer/getting-started/images/gh-url.png b/docs/content/developer/getting-started/images/gh-url.png similarity index 100% rename from docs/content/guides/developer/getting-started/images/gh-url.png rename to docs/content/developer/getting-started/images/gh-url.png diff --git a/docs/content/guides/developer/getting-started/images/releases.png b/docs/content/developer/getting-started/images/releases.png similarity index 100% rename from docs/content/guides/developer/getting-started/images/releases.png rename to docs/content/developer/getting-started/images/releases.png diff --git a/docs/content/guides/developer/getting-started/iota-environment.mdx b/docs/content/developer/getting-started/iota-environment.mdx similarity index 97% rename from docs/content/guides/developer/getting-started/iota-environment.mdx rename to docs/content/developer/getting-started/iota-environment.mdx index 8f8a0b25b8d..910f53db24b 100644 --- a/docs/content/guides/developer/getting-started/iota-environment.mdx +++ b/docs/content/developer/getting-started/iota-environment.mdx @@ -14,11 +14,11 @@ To create a local IOTA repository: 1. Go to the [IOTA repository](https://github.com/iotaledger/iota) on GitHub. 1. Click the **Fork** button to create a copy of the repository in your account. - ![Fork IOTA repo](./images/fork.png) + ![Fork IOTA repo](images/fork.png) 1. In your forked repository on GitHub, click the green `Code <>` button and copy the **HTTPS** URL GitHub provides. - ![Copy URL](./images/gh-url.png) + ![Copy URL](images/gh-url.png) 1. Open a terminal or console on your system at the location you want to save the repository locally. Type `git clone ` and paste the URL you copied in the previous step and press `Enter`. 1. Type `cd iota` to make `iota` the active directory. @@ -34,7 +34,7 @@ Be sure to synchronize your fork frequently to keep it up-to-date with active de ## Using IOTA from command line -You can interact with the IOTA network through two official SDKs (TypeScript SDK and Rust SDK), and by using the IOTA CLI. For more details about using the IOTA CLI, see [Install IOTA](./iota-install.mdx) and the [IOTA CLI](/references/cli.mdx) reference. +You can interact with the IOTA network through two official SDKs (TypeScript SDK and Rust SDK), and by using the IOTA CLI. For more details about using the IOTA CLI, see [Install IOTA](iota-install.mdx) and the [IOTA CLI](/references/cli.mdx) reference. ## Move IDEs and plugins diff --git a/docs/content/guides/developer/getting-started/iota-install.mdx b/docs/content/developer/getting-started/iota-install.mdx similarity index 96% rename from docs/content/guides/developer/getting-started/iota-install.mdx rename to docs/content/developer/getting-started/iota-install.mdx index 1bac822f0dc..c59d97be003 100644 --- a/docs/content/guides/developer/getting-started/iota-install.mdx +++ b/docs/content/developer/getting-started/iota-install.mdx @@ -3,8 +3,8 @@ title: Install IOTA description: Install the IOTA framework and required prerequisites on your system, including the IOTA command line interface to interact with the IOTA network. --- -import MacosDeps from "../../../_snippets/macos-deps.mdx"; -import LinuxDeps from "../../../_snippets/linux-deps.mdx"; +import MacosDeps from "../../_snippets/macos-deps.mdx"; +import LinuxDeps from "../../_snippets/linux-deps.mdx"; The quickest way to install IOTA is using the binaries delivered with every release. If you require more control over the install process, you can install from source. To take advantage of containerization, you can utilize the Docker images in the `docker` folder of the iota repository. @@ -49,7 +49,7 @@ Each IOTA release provides a set of binaries for several operating systems. You 1. Go to https://github.com/iotaledger/iota. 1. In the right pane, find the **Releases** section. - ![IOTA releases in GitHub](./images/releases.png) + ![IOTA releases in GitHub](images/releases.png) 1. Click the release tagged **Latest** to open the release's page. 1. In the **Assets** section of the release, select the .tgz compressed file that corresponds to your operating system. 1. Double-click the downloaded file. If the file doesn't automatically expand, manually unzip the file. @@ -372,6 +372,6 @@ cargo install --locked --git https://github.com/iotaledger/iota.git --branch tes Now that you have IOTA installed, it's time to start developing. Check out the following topics to start working with IOTA: - Read about the [IOTA CLI](/references/cli.mdx), the most straightforward way to start exploring IOTA networks. -- [Learn about the available networks](./connect.mdx) and connect to one. -- [Get some coins](./get-coins.mdx) on a development network. -- [Build your first dApp](../first-app.mdx) to start your on-chain journey. +- [Learn about the available networks](connect.mdx) and connect to one. +- [Get some coins](get-coins.mdx) on a development network. +- [Build your first dApp](first-app/first-app.mdx) to start your on-chain journey. diff --git a/docs/content/guides/developer/getting-started/local-network.mdx b/docs/content/developer/getting-started/local-network.mdx similarity index 99% rename from docs/content/guides/developer/getting-started/local-network.mdx rename to docs/content/developer/getting-started/local-network.mdx index 30d4db21d86..91427c32bc7 100644 --- a/docs/content/guides/developer/getting-started/local-network.mdx +++ b/docs/content/developer/getting-started/local-network.mdx @@ -4,7 +4,7 @@ title: Connect to a Local Network Use a IOTA local network to test your dApps against the latest changes to IOTA, and to prepare for the next IOTA release to the Devnet or Testnet network. To set up a local network, IOTA provides the `iota-test-validator` binary. The `iota-test-validator` starts a local network that includes a IOTA Full node, a IOTA validator, and a IOTA faucet. You can use the included faucet to get test IOTA to use on the local network. -If you haven't already, you need to [install IOTA](./iota-install.mdx) on your system. +If you haven't already, you need to [install IOTA](iota-install.mdx) on your system. ## Start the local network diff --git a/docs/content/concepts/graphql-rpc.mdx b/docs/content/developer/graphql-rpc.mdx similarity index 94% rename from docs/content/concepts/graphql-rpc.mdx rename to docs/content/developer/graphql-rpc.mdx index 84796041632..b796cf38e46 100644 --- a/docs/content/concepts/graphql-rpc.mdx +++ b/docs/content/developer/graphql-rpc.mdx @@ -248,7 +248,7 @@ It is an error to apply both a `first` and a `last` limit. ### Examples -To see these principles put into practice, consult the examples for [paginating forwards](../guides/developer/getting-started/graphql-rpc.mdx#page-forward) and [paginating backwards](../guides/developer/getting-started/graphql-rpc.mdx#page-back) in the getting started guide. +To see these principles put into practice, consult the examples for [paginating forwards](getting-started/graphql-rpc.mdx#paginating-checkpoints-forward-five-at-a-time-page-forward) and [paginating backwards](getting-started/graphql-rpc.mdx#paginating-checkpoints-backwards-five-at-a-time-page-back) in the getting started guide. ## Limits @@ -283,6 +283,6 @@ In addition to rate limits, queries are also validated against a number of rules ## Related links -- [GraphQL quick-start](../guides/developer/getting-started/graphql-rpc.mdx): Querying IOTA RPC with GraphQL gets you started using GraphQL to query the IOTA RPC for on-chain data. -- [GraphQL migration](../guides/developer/advanced/graphql-migration.mdx): Migrating to GraphQL guides you through migrating IOTA RPC projects from JSON-RPC to GraphQL. +- [GraphQL quick-start](getting-started/graphql-rpc.mdx): Querying IOTA RPC with GraphQL gets you started using GraphQL to query the IOTA RPC for on-chain data. +- [GraphQL migration](advanced/graphql-migration.mdx): Migrating to GraphQL guides you through migrating IOTA RPC projects from JSON-RPC to GraphQL. - [GraphQL reference](../references/iota-graphql.mdx): Auto-generated GraphQL reference for IOTA RPC. diff --git a/docs/content/guides.mdx b/docs/content/developer/guides.mdx similarity index 63% rename from docs/content/guides.mdx rename to docs/content/developer/guides.mdx index f7629ed208e..d6bd7118b15 100644 --- a/docs/content/guides.mdx +++ b/docs/content/developer/guides.mdx @@ -9,10 +9,10 @@ Often, the best way to learn a new technology is through experience. The content Instructions for common tasks, based on your role in the IOTA ecosystem. - + Guides for developers of all levels. - + Guides for validators and node operators. @@ -21,13 +21,13 @@ Guides for validators and node operators. You must crawl before you can run. Start your IOTA journey here. - + Learn about IOTA tools and the recommended development environment. - + Install IOTA on your Windows, MacOS, or Linux system. - + With IOTA installed, you're ready to start developing. @@ -36,12 +36,12 @@ With IOTA installed, you're ready to start developing. Learn the basics of IOTA and how they might differ from other blockchains. - + Transactions on IOTA are more powerful than other blockchains. Learn why and how to use them. - + - + Monitor the IOTA network and programmatically react to on-chain events. @@ -50,12 +50,12 @@ Monitor the IOTA network and programmatically react to on-chain events. Processes and guides for validators and node operators on the IOTA network. - + - + Learn how to operate a Full node on IOTA. - + Optimize your Full node configuration for efficient node operation. diff --git a/docs/content/guides/developer/iota-101.mdx b/docs/content/developer/iota-101.mdx similarity index 84% rename from docs/content/guides/developer/iota-101.mdx rename to docs/content/developer/iota-101.mdx index a511c72b0fd..8f56ee88524 100644 --- a/docs/content/guides/developer/iota-101.mdx +++ b/docs/content/developer/iota-101.mdx @@ -9,29 +9,29 @@ In many education systems, 101-level classes are those that teach core competenc Everything on the IOTA blockchain is an object. These topics use code examples to demonstrate how to create these specific types of objects. -- [Create Coins](./iota-101/create-coin.mdx) -- [Create NFTs](./iota-101/create-nft.mdx) +- [Create Coins](iota-101/create-coin/create-coin.mdx) +- [Create NFTs](iota-101/create-nft.mdx) ## Working with PTBs You can create programmable transaction blocks (PTBs) on IOTA to perform multiple commands in a single transaction. The Working with PTBs topics demonstrate how to build efficient PTBs using the IOTA TypeScript SDK. -Go to [Working with PTBs](./iota-101/working-with-ptbs.mdx). +Go to [Working with PTBs](iota-101/transactions/ptb/working-with-ptbs.mdx). ## Using Events You can emit events from your published packages on the IOTA network. Using Events demonstrates how to emit events from your on-chain packages and monitor the activity of other objects emitting events. -Go to [Using Events](./iota-101/using-events.mdx). +Go to [Using Events](iota-101/using-events.mdx). ## Shared versus Owned Objects Objects on IOTA, unlike other blockchains, can be owned as well as shared. You can create transactions that leverage either type or both. Shared versus Owned Objects examines the differences and what considerations you should account for when deciding how to structure your on-chain app. -Go to [Shared versus Owned Objects](./iota-101/shared-owned.mdx). +Go to [Shared versus Owned Objects](iota-101/objects/shared-owned.mdx). ## Access On-Chain Time IOTA provides a `Clock` module you can use to get network-based time. Access On-Chain Time examines the `Clock` module and the behavior of the available methods that affect transaction processing speed and the temporal exactness of the data you receive. -Go to [Access On-Chain Time](./iota-101/access-time.mdx). \ No newline at end of file +Go to [Access On-Chain Time](iota-101/access-time.mdx). \ No newline at end of file diff --git a/docs/content/guides/developer/iota-101/access-time.mdx b/docs/content/developer/iota-101/access-time.mdx similarity index 100% rename from docs/content/guides/developer/iota-101/access-time.mdx rename to docs/content/developer/iota-101/access-time.mdx diff --git a/docs/content/guides/developer/iota-101/create-coin.mdx b/docs/content/developer/iota-101/create-coin/create-coin.mdx similarity index 87% rename from docs/content/guides/developer/iota-101/create-coin.mdx rename to docs/content/developer/iota-101/create-coin/create-coin.mdx index b3ec85e3bba..289b4f55f66 100644 --- a/docs/content/guides/developer/iota-101/create-coin.mdx +++ b/docs/content/developer/iota-101/create-coin/create-coin.mdx @@ -2,9 +2,9 @@ title: Create Coins and Tokens --- -Coins and tokens on IOTA are similar. In practice, the terms are used interchangeably, but there are some differences in their implementation. You can learn about these differences in the respective standard documentation, [Closed-Loop Token](../../../standards/closed-loop-token.mdx) and [Coin](../../../standards/coin.mdx). +Coins and tokens on IOTA are similar. In practice, the terms are used interchangeably, but there are some differences in their implementation. You can learn about these differences in the respective standard documentation, [Closed-Loop Token](../../standards/closed-loop-token.mdx) and [Coin](../../standards/coin.mdx). -Publishing a coin on IOTA is nearly as straightforward as publishing a new type. The main difference is the requirement of a [one-time witness](/concepts/iota-move-concepts/one-time-witness.mdx) when creating a coin. +Publishing a coin on IOTA is nearly as straightforward as publishing a new type. The main difference is the requirement of a [one-time witness](../iota-move-concepts/one-time-witness.mdx) when creating a coin. ```move module examples::mycoin { @@ -89,12 +89,12 @@ Coin-like functions perform the minting and burning of tokens. Both require the - `token::mint` - mint a token - `token::burn` - burn a token -See [Closed-Loop Token](../../../standards/closed-loop-token.mdx) standard for complete details of working with tokens. +See [Closed-Loop Token](../../standards/closed-loop-token.mdx) standard for complete details of working with tokens. ## Examples See the following topics for examples of some common use cases for coin and token creation. -- [Regulated Coin and Deny List](./create-coin/regulated.mdx): Create a regulated coin and add or remove names from the deny list. -- [Loyalty Token](./create-coin/loyalty.mdx): Create a token to reward user loyalty. -- [In-Game Token](./create-coin/in-game-token.mdx): Create tokens that can be used only within a mobile game. +- [Regulated Coin and Deny List](regulated.mdx): Create a regulated coin and add or remove names from the deny list. +- [Loyalty Token](loyalty.mdx): Create a token to reward user loyalty. +- [In-Game Token](in-game-token.mdx): Create tokens that can be used only within a mobile game. diff --git a/docs/content/guides/developer/iota-101/create-coin/in-game-token.mdx b/docs/content/developer/iota-101/create-coin/in-game-token.mdx similarity index 90% rename from docs/content/guides/developer/iota-101/create-coin/in-game-token.mdx rename to docs/content/developer/iota-101/create-coin/in-game-token.mdx index 1ecf0243c36..90c6f834c55 100644 --- a/docs/content/guides/developer/iota-101/create-coin/in-game-token.mdx +++ b/docs/content/developer/iota-101/create-coin/in-game-token.mdx @@ -2,7 +2,7 @@ title: In-Game Currency --- -Using the IOTA [Closed-Loop Token](../../../../standards/closed-loop-token.mdx) standard, you can create in-game currency (such as gems or diamonds in mobile games) that you can grant to players for their actions or make available to purchase. You mint the tokens on IOTA, but players can only use the tokens within the economy of the game itself. These types of tokens are usually not transferrable and you would typically mint them in predefined amounts to maintain scarcity and game balance. +Using the IOTA [Closed-Loop Token](../../standards/closed-loop-token.mdx) standard, you can create in-game currency (such as gems or diamonds in mobile games) that you can grant to players for their actions or make available to purchase. You mint the tokens on IOTA, but players can only use the tokens within the economy of the game itself. These types of tokens are usually not transferrable and you would typically mint them in predefined amounts to maintain scarcity and game balance. The following example creates an in-game currency called a GEM, which represents a certain number of IOTA. In the example, the user can buy fungible GEMs using IOTA, which can then be used as currency within the game. Use the code comments to follow the logic of the example. diff --git a/docs/content/guides/developer/iota-101/create-coin/loyalty.mdx b/docs/content/developer/iota-101/create-coin/loyalty.mdx similarity index 93% rename from docs/content/guides/developer/iota-101/create-coin/loyalty.mdx rename to docs/content/developer/iota-101/create-coin/loyalty.mdx index fc8b0937170..2ecdbbb81cd 100644 --- a/docs/content/guides/developer/iota-101/create-coin/loyalty.mdx +++ b/docs/content/developer/iota-101/create-coin/loyalty.mdx @@ -2,7 +2,7 @@ title: Loyalty Tokens --- -Using the IOTA [Closed-Loop Token](../../../../standards/closed-loop-token.mdx) standard, you can create tokens that are valid only for a specific service, like an airline that wants to grant tokens to frequent flyers to purchase tickets or upgrades. +Using the IOTA [Closed-Loop Token](../../standards/closed-loop-token.mdx) standard, you can create tokens that are valid only for a specific service, like an airline that wants to grant tokens to frequent flyers to purchase tickets or upgrades. The following example demonstrates the creation of a loyalty token that bearers can use to make purchases in a digital gift shop. Use the comments in the code to follow the logic of the example. diff --git a/docs/content/guides/developer/iota-101/create-coin/regulated.mdx b/docs/content/developer/iota-101/create-coin/regulated.mdx similarity index 89% rename from docs/content/guides/developer/iota-101/create-coin/regulated.mdx rename to docs/content/developer/iota-101/create-coin/regulated.mdx index f2112c9384a..c1e11ee827c 100644 --- a/docs/content/guides/developer/iota-101/create-coin/regulated.mdx +++ b/docs/content/developer/iota-101/create-coin/regulated.mdx @@ -3,7 +3,7 @@ title: Regulated Coin and Deny List description: You can create regulated coins on IOTA, such as stablecoins. These coins are similar to other coins like IOTA, but include the ability to control access to the coin using a deny list. --- -The IOTA [Coin](../../../../standards/coin.mdx) standard provides a `create_regulated_currency` function to create coins. This function is different than `create_currency` in that it generates a coin that you can block certain addresses from being able to use those coins in transactions. This ability is a requirement for assets like stablecoins. +The IOTA [Coin](../../standards/coin.mdx) standard provides a `create_regulated_currency` function to create coins. This function is different than `create_currency` in that it generates a coin that you can block certain addresses from being able to use those coins in transactions. This ability is a requirement for assets like stablecoins. Behind the scenes, `create_regulated_currency` uses the `create_currency` function to create the coin, but also produces a `DenyCap` object that allows its bearer to control access to the coin's deny list in a `DenyList` object. Consequently, the way to create a coin using `create_regulated_currency` is similar to the previous example, with the addition of a transfer of the `DenyCap` object to the module publisher. @@ -75,7 +75,7 @@ Created Objects: As you might have noticed, the publish action creates a `RegulatedCoinMetadata` object along with the standard `CoinMetadata` object. You don't need to explicitly call the `freeze_object` on the `RegulatedCoinMetadata` object, however, because `create_regulated_currency` automatically performs this action. -The output also shows the three objects that the publisher now owns: `UpgradeCap` for [package upgrades](../../../../concepts/iota-move-concepts/packages/upgrade.mdx), `TreasuryCap` for minting or burning coins, and the `DenyCap` for adding or removing addresses to or from the deny list for this coin. +The output also shows the three objects that the publisher now owns: `UpgradeCap` for [package upgrades](../iota-move-concepts/packages/upgrade.mdx), `TreasuryCap` for minting or burning coins, and the `DenyCap` for adding or removing addresses to or from the deny list for this coin. ## DenyList diff --git a/docs/content/guides/developer/iota-101/create-nft.mdx b/docs/content/developer/iota-101/create-nft.mdx similarity index 100% rename from docs/content/guides/developer/iota-101/create-nft.mdx rename to docs/content/developer/iota-101/create-nft.mdx diff --git a/docs/content/concepts/iota-move-concepts/collections.mdx b/docs/content/developer/iota-101/iota-move-concepts/collections.mdx similarity index 77% rename from docs/content/concepts/iota-move-concepts/collections.mdx rename to docs/content/developer/iota-101/iota-move-concepts/collections.mdx index 9e070f75245..2ab48fcc1b3 100644 --- a/docs/content/concepts/iota-move-concepts/collections.mdx +++ b/docs/content/developer/iota-101/iota-move-concepts/collections.mdx @@ -9,19 +9,19 @@ Collections provide a convenient way to work with groups of data. The IOTA frame A bag is a heterogeneous map-like collection. The collection is similar to `iota::table` in that its keys and values are not stored within the Bag value, but instead are stored using IOTA's object system. The Bag struct acts only as a handle into the object system to retrieve those keys and values. This means that Bag values with exactly the same key-value mapping will not be equal, with ==, at runtime. -To learn more, see [Table and Bag](../dynamic-fields/tables-bags.mdx) or the [framework definition](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/docs/iota-framework/bag.md) on GitHub. +To learn more, see [Table and Bag](../objects/dynamic-fields/tables-bags.mdx) or the [framework definition](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/docs/iota-framework/bag.md) on GitHub. ## dynamic_field In addition to the fields declared in its type definition, a IOTA object can have dynamic fields that can be added after the object has been constructed. Unlike ordinary field names (which are always statically declared identifiers) a dynamic field name can be any value with the copy, drop, and store abilities (for example, an integer, a boolean, or a string). This gives IOTA programmers the flexibility to extend objects on-the-fly, and it also serves as a building block for core collection types. -To learn more, see [Dynamic Fields](../dynamic-fields.mdx) or the [framework definition](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/docs/iota-framework/dynamic_field.md) on GitHub. +To learn more, see [Dynamic Fields](../objects/dynamic-fields/dynamic-fields.mdx) or the [framework definition](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/docs/iota-framework/dynamic_field.md) on GitHub. ## dynamic_object_field Similar to `iota::dynamic_field`, this module allows for the access of dynamic fields. But unlike, `iota::dynamic_field` the values bound to these dynamic fields must be objects themselves. This allows for the objects to still exist within storage, which may be important for external tools. The difference is otherwise not observable from within Move. -To learn more, see [Dynamic Fields](../dynamic-fields.mdx) or the [framework definition](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/docs/iota-framework/dynamic_object_field.md) on GitHub. +To learn more, see [Dynamic Fields](../objects/dynamic-fields/dynamic-fields.mdx) or the [framework definition](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/docs/iota-framework/dynamic_object_field.md) on GitHub. ## linked_table @@ -33,13 +33,13 @@ To learn more, see the [framework definition](https://github.com/iotaledger/iota Similar to `iota::bag`, an `ObjectBag` is a heterogeneous map-like collection. But unlike `iota::bag`, the values bound to these dynamic fields must be objects themselves. This allows for the objects to still exist in storage, which might be important for external tools. The difference is otherwise not observable from within Move. -To learn more, see [Table and Bag](../dynamic-fields/tables-bags.mdx) or the [framework definition](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/docs/iota-framework/object_bag.md) on GitHub. +To learn more, see [Table and Bag](../objects/dynamic-fields/tables-bags.mdx) or the [framework definition](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/docs/iota-framework/object_bag.md) on GitHub. ## object_table Similar to `iota::table`, an `ObjectTable` is a map-like collection. But unlike `iota::table`, the values bound to these dynamic fields must be objects themselves. This allows for the objects to still exist within in storage, which may be important for external tools. The difference is otherwise not observable from within Move. -To learn more, see [Table and Bag](../dynamic-fields/tables-bags.mdx) or the [framework definition](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/docs/iota-framework/object_table.md) on GitHub. +To learn more, see [Table and Bag](../objects/dynamic-fields/tables-bags.mdx) or the [framework definition](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/docs/iota-framework/object_table.md) on GitHub. ## priority_queue @@ -51,7 +51,7 @@ To learn more, see the [framework definition](https://github.com/iotaledger/iota A table is a map-like collection. But unlike a traditional collection, its keys and values are not stored within the Table value, but instead are stored using IOTA's object system. The Table struct acts only as a handle into the object system to retrieve those keys and values. Note that this means that Table values with exactly the same key-value mapping will not be equal, with ==, at runtime. -To learn more, see [Table and Bag](../dynamic-fields/tables-bags.mdx) or the [framework definition](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/docs/iota-framework/table.md) on GitHub. +To learn more, see [Table and Bag](../objects/dynamic-fields/tables-bags.mdx) or the [framework definition](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/docs/iota-framework/table.md) on GitHub. ## table_vec diff --git a/docs/content/concepts/iota-move-concepts/conventions.mdx b/docs/content/developer/iota-101/iota-move-concepts/conventions.mdx similarity index 100% rename from docs/content/concepts/iota-move-concepts/conventions.mdx rename to docs/content/developer/iota-101/iota-move-concepts/conventions.mdx diff --git a/docs/content/concepts/iota-move-concepts/entry-functions.mdx b/docs/content/developer/iota-101/iota-move-concepts/entry-functions.mdx similarity index 100% rename from docs/content/concepts/iota-move-concepts/entry-functions.mdx rename to docs/content/developer/iota-101/iota-move-concepts/entry-functions.mdx diff --git a/docs/content/concepts/iota-move-concepts/init.mdx b/docs/content/developer/iota-101/iota-move-concepts/init.mdx similarity index 100% rename from docs/content/concepts/iota-move-concepts/init.mdx rename to docs/content/developer/iota-101/iota-move-concepts/init.mdx diff --git a/docs/content/concepts/iota-move-concepts.mdx b/docs/content/developer/iota-101/iota-move-concepts/iota-move-concepts.mdx similarity index 74% rename from docs/content/concepts/iota-move-concepts.mdx rename to docs/content/developer/iota-101/iota-move-concepts/iota-move-concepts.mdx index 6e49342f4f7..46001ec75bf 100644 --- a/docs/content/concepts/iota-move-concepts.mdx +++ b/docs/content/developer/iota-101/iota-move-concepts/iota-move-concepts.mdx @@ -3,11 +3,11 @@ title: Move Concepts description: Move is an open source language for writing safe packages to manipulate on-chain objects --- -import MoveSummary from "../_snippets/move-summary.mdx"; +import MoveSummary from "../../../_snippets/move-summary.mdx"; -You can use Move to define, create, and manage programmable IOTA objects representing user-level assets. IOTA's object system is implemented by adding new functionality to Move while also imposing additional restrictions. See [Object Model](./object-model.mdx) for more details. +You can use Move to define, create, and manage programmable IOTA objects representing user-level assets. IOTA's object system is implemented by adding new functionality to Move while also imposing additional restrictions. See [Object Model](./../objects/object-model.mdx) for more details. ## Move on IOTA @@ -26,17 +26,17 @@ In general, Move on Diem code written for other systems works in IOTA with these - [Global storage operators](https://move-language.github.io/move/global-storage-operators.html) - [Key abilities](https://github.com/move-language/move/blob/main/language/documentation/book/src/abilities.md) -## Key differences {#differences} +## Key differences Key differences with Move on IOTA include: -- IOTA uses its own [object-centric global storage](#global-storage) -- Addresses represent [Object IDs](#object-ids) -- IOTA objects have [globally unique IDs](#global-unique) +- IOTA uses its own [object-centric global storage](#object-centric-global-storage) +- Addresses represent [Object IDs](#addresses-represent-object-ids) +- IOTA objects have [globally unique IDs](#object-with-key-ability-globally-unique-ids) - IOTA has [module initializers](#module-initializers) (init) -- IOTA [entry points](#entry-points) take object references as input +- IOTA [entry points](#entry-points-take-object-references-as-input) take object references as input -### Object-centric global storage {#global-storage} +### Object-centric global storage In Move on Diem, global storage is part of the programming model. Resources and modules are held in global storage, owned by an account which has an address. Transactions are free to access resources from any account in global storage when they run, using special operations such as `move_to` and `move_from`. @@ -44,27 +44,27 @@ This approach introduces a scaling issue, as it is not possible to statically de Move on IOTA addresses the scaling issue by not having global storage, or its related operations. When objects (in contrast to resources) and packages (sets of modules) are stored on IOTA, they are each given unique identifiers. All a transaction's inputs are explicitly specified up-front using these unique identifiers, to allow the chain to schedule transactions with non-overlapping inputs in parallel. -### Addresses represent Object IDs {#object-ids} +### Addresses represent Object IDs In Move on Diem, there is a 16-byte `address` type used to represent account addresses in global storage. A 16 byte address is sufficient for the Move on Diem security model. IOTA doesn't have global storage, so `address` is re-purposed as a 32-byte identifier used for both objects and accounts. Each transaction is signed by an account (the "sender") that is accessible from the transaction context, and each object stores its `address` wrapped in its `id: UID` field. (Refer to [object.move](https://github.com/iotaledger/iota/tree/main/crates/iota-framework/packages/iota-framework/sources/object.move) in the IOTA framework for details). -### Object with key ability, globally unique IDs {#global-unique} +### Object with key ability, globally unique IDs In Move on Diem, the `key` ability indicates that the type is a resource, meaning it (along with an account address) can be used as a key in global storage. On IOTA, the `key` ability indicates that a struct is an object type and comes with an additional requirement that the first field of the struct has signature `id: UID`, to contain the object's unique address on-chain. IOTA's bytecode verifier ensures that new objects are always assigned fresh `UID`s (identifiers are never re-used). -### Module initializers {#module-initializers} +### Module initializers -As described in [Object-centric global storage](#global-storage), you publish Move modules into IOTA storage. The IOTA runtime executes a special [initializer function](./iota-move-concepts/init.mdx) you optionally define in a module only once at the time of module publication to pre-initialize module-specific data (for example, creating singleton objects). +As described in [Object-centric global storage](#object-centric-global-storage), you publish Move modules into IOTA storage. The IOTA runtime executes a special [initializer function](init.mdx) you optionally define in a module only once at the time of module publication to pre-initialize module-specific data (for example, creating singleton objects). -### Entry points take object references as input {#entry-points} +### Entry points take object references as input You can call public functions from IOTA transactions (called programmable transaction blocks). These functions can take objects by value, by immutable reference, or by mutable reference. If taken by value, you can destroy the object, wrap it (in another object), or transfer it (to a IOTA ID specified by an address). If taken by mutable reference, the modified version of the object saves to storage without any change in ownership. In any case, the IOTA network authenticates the object and declares it's usage as a part of the transaction. -In addition to calling public functions, you can call a function that is marked [entry](./iota-move-concepts/entry-functions.mdx) even if it is private as long as other non-`entry` functions have not used its inputs. +In addition to calling public functions, you can call a function that is marked [entry](entry-functions.mdx) even if it is private as long as other non-`entry` functions have not used its inputs. ## Explore concepts @@ -73,20 +73,20 @@ Some of the features of Move are defined in this section using commented code ex ### Init -The `init` function is a special function that executes only once - when you publish the associated module. See [Init](./iota-move-concepts/init.mdx) for details. +The `init` function is a special function that executes only once - when you publish the associated module. See [Init](init.mdx) for details. ### Entry functions -The `entry` modifier for functions enables safe and direct invocation of module functions, much like scripts. See [Entry](./iota-move-concepts/entry-functions.mdx) for details. +The `entry` modifier for functions enables safe and direct invocation of module functions, much like scripts. See [Entry](entry-functions.mdx) for details. ### Strings -Move does not have a native type for strings, but it has a useful wrapper. See [Strings](./iota-move-concepts/strings.mdx) for examples. +Move does not have a native type for strings, but it has a useful wrapper. See [Strings](strings.mdx) for examples. ### One-time witness -A one-time witness (OTW) is a special instance of a type created in the module initializer and guaranteed to be unique with only one instance. See [One-Time Witness](./iota-move-concepts/one-time-witness.mdx) for an example. +A one-time witness (OTW) is a special instance of a type created in the module initializer and guaranteed to be unique with only one instance. See [One-Time Witness](one-time-witness.mdx) for an example. ### Patterns -Move coding patterns, or techniques, solve logic problems you encounter when developing Move packages for the IOTA blockchain. See the [Patterns](./iota-move-concepts/patterns.mdx) section for a list of documented coding patterns. +Move coding patterns, or techniques, solve logic problems you encounter when developing Move packages for the IOTA blockchain. See the [Patterns](patterns.mdx) section for a list of documented coding patterns. diff --git a/docs/content/concepts/iota-move-concepts/move-on-iota.mdx b/docs/content/developer/iota-101/iota-move-concepts/move-on-iota.mdx similarity index 100% rename from docs/content/concepts/iota-move-concepts/move-on-iota.mdx rename to docs/content/developer/iota-101/iota-move-concepts/move-on-iota.mdx diff --git a/docs/content/concepts/iota-move-concepts/one-time-witness.mdx b/docs/content/developer/iota-101/iota-move-concepts/one-time-witness.mdx similarity index 100% rename from docs/content/concepts/iota-move-concepts/one-time-witness.mdx rename to docs/content/developer/iota-101/iota-move-concepts/one-time-witness.mdx diff --git a/docs/content/concepts/iota-move-concepts/packages/custom-policies.mdx b/docs/content/developer/iota-101/iota-move-concepts/packages/custom-policies.mdx similarity index 99% rename from docs/content/concepts/iota-move-concepts/packages/custom-policies.mdx rename to docs/content/developer/iota-101/iota-move-concepts/packages/custom-policies.mdx index 39173a7bb7f..257da7f1886 100644 --- a/docs/content/concepts/iota-move-concepts/packages/custom-policies.mdx +++ b/docs/content/developer/iota-101/iota-move-concepts/packages/custom-policies.mdx @@ -2,13 +2,13 @@ title: Custom Upgrade Policies --- -import UpgradeSingleKeyRisk from "../../../_snippets/upgrade-single-key-risk.mdx"; +import UpgradeSingleKeyRisk from "../../../../_snippets/upgrade-single-key-risk.mdx"; Protecting the ability to upgrade a package on chain using a single key can pose a security risk for several reasons: -To address the security risk of single-key upgrade ownership poses while still providing the opportunity to [upgrade live packages](./upgrade.mdx), IOTA offers _custom upgrade policies_. These policies protect `UpgradeCap` access and issue `UpgradeTicket` objects that authorize upgrades on a case-by-case basis. +To address the security risk of single-key upgrade ownership poses while still providing the opportunity to [upgrade live packages](upgrade.mdx), IOTA offers _custom upgrade policies_. These policies protect `UpgradeCap` access and issue `UpgradeTicket` objects that authorize upgrades on a case-by-case basis. ## Compatibility {#compatibility} diff --git a/docs/content/concepts/iota-move-concepts/packages.mdx b/docs/content/developer/iota-101/iota-move-concepts/packages/packages.mdx similarity index 91% rename from docs/content/concepts/iota-move-concepts/packages.mdx rename to docs/content/developer/iota-101/iota-move-concepts/packages/packages.mdx index b44c565f12f..da9e76c0e55 100644 --- a/docs/content/concepts/iota-move-concepts/packages.mdx +++ b/docs/content/developer/iota-101/iota-move-concepts/packages/packages.mdx @@ -3,7 +3,7 @@ title: Package Upgrades description: A Move package on IOTA includes one or more modules that define that package's interaction with on-chain objects. Upgrading on-chain packages provides a way to improve your code or add features without affecting packages that use your published modules. --- -import UpgradeSingleKeyRisk from "../../_snippets/upgrade-single-key-risk.mdx"; +import UpgradeSingleKeyRisk from "../../../../_snippets/upgrade-single-key-risk.mdx"; A Move package on IOTA includes one or more modules that define that package's interaction with on-chain objects. You develop the logic for those modules using Move, which you then compile into an object. Finally, you publish your package object onto a IOTA network. On chain, anyone can view your package contents and the logic it employs to manipulate other on-chain objects using a IOTA network explorer. @@ -13,7 +13,7 @@ After you publish a package object on chain to a network, it lives there forever ## Upgrading packages -While you can't manipulate on-chain packages directly, you do have the ability to upgrade them. Upgrading on-chain packages provides a way to improve your code or add features without affecting packages that use the original package. When you upgrade a package, you're creating a new object on chain instead of modifying the original package. See [Upgrading Packages](./packages/upgrade.mdx) to learn more about the process. +While you can't manipulate on-chain packages directly, you do have the ability to upgrade them. Upgrading on-chain packages provides a way to improve your code or add features without affecting packages that use the original package. When you upgrade a package, you're creating a new object on chain instead of modifying the original package. See [Upgrading Packages](upgrade.mdx) to learn more about the process. ## Using IOTA Client CLI to upgrade packages @@ -27,4 +27,4 @@ Using the IOTA CLI is useful to get started with upgrades, or in the early stage You can make a package _immutable_ when it goes live to mitigate the single-key risk using the Move `iota::package::make_immutable` function to destroy its `UpgradeCap`. Making the package immutable, however, prevents future bug fixes and new features, which might not be practical or desired. -To protect your package from single-key risk on chain, see [Custom Upgrade Policies](./packages/custom-policies.mdx). +To protect your package from single-key risk on chain, see [Custom Upgrade Policies](custom-policies.mdx). diff --git a/docs/content/concepts/iota-move-concepts/packages/upgrade.mdx b/docs/content/developer/iota-101/iota-move-concepts/packages/upgrade.mdx similarity index 98% rename from docs/content/concepts/iota-move-concepts/packages/upgrade.mdx rename to docs/content/developer/iota-101/iota-move-concepts/packages/upgrade.mdx index 85217fd6cfd..190b8517a4c 100644 --- a/docs/content/concepts/iota-move-concepts/packages/upgrade.mdx +++ b/docs/content/developer/iota-101/iota-move-concepts/packages/upgrade.mdx @@ -3,7 +3,7 @@ title: Upgrading Packages description: IOTA provides a method of upgrading your packages while still retaining their immutable properties. --- -IOTA smart contracts are immutable package objects consisting of a collection of Move modules. Because the packages are immutable, transactions can safely access smart contracts without full consensus (fastpath transactions). If someone could change these packages, they would become [shared objects](/concepts/object-ownership/shared.mdx#shared), which would require full consensus before completing a transaction. +IOTA smart contracts are immutable package objects consisting of a collection of Move modules. Because the packages are immutable, transactions can safely access smart contracts without full consensus (fastpath transactions). If someone could change these packages, they would become [shared objects](../../objects/object-ownership/shared.mdx), which would require full consensus before completing a transaction. The inability to change package objects, however, becomes a problem when considering the iterative nature of code development. Builders require the ability to update their code and pull changes from other developers while still being able to reap the benefits of fastpath transactions. Fortunately, the IOTA network provides a method of upgrading your packages while still retaining their immutable properties. @@ -409,7 +409,7 @@ With the new manifest and code in place, it's time to use the `iota client upgra iota client upgrade --gas-budget --upgrade-capability ``` -The console alerts you if the new package doesn't satisfy [requirements](#requirements), otherwise the compiler publishes the upgraded package to the network and returns its result: +The console alerts you if the new package doesn't satisfy [requirements](#upgrade-requirements), otherwise the compiler publishes the upgraded package to the network and returns its result: ```shell INCLUDING DEPENDENCY Iota diff --git a/docs/content/concepts/iota-move-concepts/patterns.mdx b/docs/content/developer/iota-101/iota-move-concepts/patterns.mdx similarity index 93% rename from docs/content/concepts/iota-move-concepts/patterns.mdx rename to docs/content/developer/iota-101/iota-move-concepts/patterns.mdx index ca0e59d8891..fbf9b1ed572 100644 --- a/docs/content/concepts/iota-move-concepts/patterns.mdx +++ b/docs/content/developer/iota-101/iota-move-concepts/patterns.mdx @@ -7,7 +7,7 @@ Topics in this section introduce Move coding patterns that solve various logic n ## Capabilities -A capability is a pattern that allows authorizing actions with an object. See [Capabilities](./patterns/capabilities.mdx) for an example of this pattern. +A capability is a pattern that allows authorizing actions with an object. See [Capabilities](patterns/capabilities.mdx) for an example of this pattern. ## Witness and transferrable witness diff --git a/docs/content/concepts/iota-move-concepts/patterns/capabilities.mdx b/docs/content/developer/iota-101/iota-move-concepts/patterns/capabilities.mdx similarity index 100% rename from docs/content/concepts/iota-move-concepts/patterns/capabilities.mdx rename to docs/content/developer/iota-101/iota-move-concepts/patterns/capabilities.mdx diff --git a/docs/content/concepts/iota-move-concepts/patterns/hot-potato.mdx b/docs/content/developer/iota-101/iota-move-concepts/patterns/hot-potato.mdx similarity index 100% rename from docs/content/concepts/iota-move-concepts/patterns/hot-potato.mdx rename to docs/content/developer/iota-101/iota-move-concepts/patterns/hot-potato.mdx diff --git a/docs/content/concepts/iota-move-concepts/patterns/id-pointer.mdx b/docs/content/developer/iota-101/iota-move-concepts/patterns/id-pointer.mdx similarity index 100% rename from docs/content/concepts/iota-move-concepts/patterns/id-pointer.mdx rename to docs/content/developer/iota-101/iota-move-concepts/patterns/id-pointer.mdx diff --git a/docs/content/concepts/iota-move-concepts/patterns/transferrable-witness.mdx b/docs/content/developer/iota-101/iota-move-concepts/patterns/transferrable-witness.mdx similarity index 100% rename from docs/content/concepts/iota-move-concepts/patterns/transferrable-witness.mdx rename to docs/content/developer/iota-101/iota-move-concepts/patterns/transferrable-witness.mdx diff --git a/docs/content/concepts/iota-move-concepts/patterns/witness.mdx b/docs/content/developer/iota-101/iota-move-concepts/patterns/witness.mdx similarity index 100% rename from docs/content/concepts/iota-move-concepts/patterns/witness.mdx rename to docs/content/developer/iota-101/iota-move-concepts/patterns/witness.mdx diff --git a/docs/content/concepts/iota-move-concepts/strings.mdx b/docs/content/developer/iota-101/iota-move-concepts/strings.mdx similarity index 100% rename from docs/content/concepts/iota-move-concepts/strings.mdx rename to docs/content/developer/iota-101/iota-move-concepts/strings.mdx diff --git a/docs/content/concepts/dynamic-fields.mdx b/docs/content/developer/iota-101/objects/dynamic-fields/dynamic-fields.mdx similarity index 99% rename from docs/content/concepts/dynamic-fields.mdx rename to docs/content/developer/iota-101/objects/dynamic-fields/dynamic-fields.mdx index 985fe2d1cae..e68db1b9294 100644 --- a/docs/content/concepts/dynamic-fields.mdx +++ b/docs/content/developer/iota-101/objects/dynamic-fields/dynamic-fields.mdx @@ -194,4 +194,4 @@ Similar to borrowing a field, a transaction that attempts to remove a non-existe It is possible to delete an object that has (potentially non-`drop`) dynamic fields still defined on it. Because field values can be accessed only via the dynamic field's associated object and field name, deleting an object that has dynamic fields still defined on it renders them all inaccessible to future transactions. This is true regardless of whether the field's value has the `drop` ability. This might not be a concern when adding a small number of statically known additional fields to an object, but is particularly undesirable for on-chain collection types that could be holding unboundedly many key-value pairs as dynamic fields. -IOTA provides `Table` and `Bag` collections built using dynamic fields, but with additional support to count the number of entries they contain to protect against accidental deletion when non-empty. To learn more, see [Tables and Bags](./dynamic-fields/tables-bags.mdx). +IOTA provides `Table` and `Bag` collections built using dynamic fields, but with additional support to count the number of entries they contain to protect against accidental deletion when non-empty. To learn more, see [Tables and Bags](tables-bags.mdx). diff --git a/docs/content/concepts/dynamic-fields/tables-bags.mdx b/docs/content/developer/iota-101/objects/dynamic-fields/tables-bags.mdx similarity index 94% rename from docs/content/concepts/dynamic-fields/tables-bags.mdx rename to docs/content/developer/iota-101/objects/dynamic-fields/tables-bags.mdx index 21531e8ae0c..ef3d2a681ed 100644 --- a/docs/content/concepts/dynamic-fields/tables-bags.mdx +++ b/docs/content/developer/iota-101/objects/dynamic-fields/tables-bags.mdx @@ -3,7 +3,7 @@ title: Table and Bag description: IOTA provides `Table` and `Bag` collections built using dynamic fields, but with additional support to count the number of entries they contain to protect against accidental deletion when non-empty. --- -You can extend existing objects using [dynamic fields](../dynamic-fields.mdx). Note that it's possible to delete an object that still has (potentially non-drop) dynamic fields. This might not be a concern when adding a small number of statically known additional fields to an object, but is particularly undesirable for on-chain collection types that could be holding unboundedly many key-value pairs as dynamic fields. +You can extend existing objects using [dynamic fields](dynamic-fields.mdx). Note that it's possible to delete an object that still has (potentially non-drop) dynamic fields. This might not be a concern when adding a small number of statically known additional fields to an object, but is particularly undesirable for on-chain collection types that could be holding unboundedly many key-value pairs as dynamic fields. This topic describes two such collections -- Table and Bag -- built using dynamic fields, but with additional support to count the number of entries they contain, and protect against accidental deletion when non-empty. diff --git a/docs/content/concepts/events.mdx b/docs/content/developer/iota-101/objects/events.mdx similarity index 96% rename from docs/content/concepts/events.mdx rename to docs/content/developer/iota-101/objects/events.mdx index 7f151ee8c1f..56cc5437917 100644 --- a/docs/content/concepts/events.mdx +++ b/docs/content/developer/iota-101/objects/events.mdx @@ -104,4 +104,4 @@ module examples::donuts_with_events { ## Related links -- [Using Events](/guides/developer/iota-101/using-events.mdx): A guide to leveraging IOTA events in your smart contracts. \ No newline at end of file +- [Using Events](/developer/iota-101/using-events.mdx): A guide to leveraging IOTA events in your smart contracts. \ No newline at end of file diff --git a/docs/content/concepts/object-model.mdx b/docs/content/developer/iota-101/objects/object-model.mdx similarity index 97% rename from docs/content/concepts/object-model.mdx rename to docs/content/developer/iota-101/objects/object-model.mdx index 1730a8550e2..633295d663a 100644 --- a/docs/content/concepts/object-model.mdx +++ b/docs/content/developer/iota-101/objects/object-model.mdx @@ -13,9 +13,9 @@ The basic unit of storage in IOTA is the object. In contrast to many other block Each IOTA object has the following metadata: - A 32-byte globally unique ID. An object ID is derived from the digest of the transaction that created the object and from a counter encoding the number of IDs generated by the transaction. -- An 8-byte unsigned integer version that monotonically increases with every transaction that modifies it (see [Object and package versioning](./versioning.mdx)). +- An 8-byte unsigned integer version that monotonically increases with every transaction that modifies it (see [Object and package versioning](versioning.mdx)). - A 32-byte transaction digest indicating the last transaction that included this object as an output. -- A 33-byte owner field that indicates how this object can be accessed. See [Object Ownership](./object-ownership.mdx) for more information. +- A 33-byte owner field that indicates how this object can be accessed. See [Object Ownership](object-ownership/object-ownership.mdx) for more information. In addition to common metadata, objects have a category-specific, variable-sized contents field containing a [Binary Canonical Serialization (BCS)](https://docs.rs/bcs/latest/bcs/)-encoded payload. diff --git a/docs/content/concepts/object-ownership/address-owned.mdx b/docs/content/developer/iota-101/objects/object-ownership/address-owned.mdx similarity index 100% rename from docs/content/concepts/object-ownership/address-owned.mdx rename to docs/content/developer/iota-101/objects/object-ownership/address-owned.mdx diff --git a/docs/content/concepts/object-ownership/immutable.mdx b/docs/content/developer/iota-101/objects/object-ownership/immutable.mdx similarity index 100% rename from docs/content/concepts/object-ownership/immutable.mdx rename to docs/content/developer/iota-101/objects/object-ownership/immutable.mdx diff --git a/docs/content/concepts/object-ownership.mdx b/docs/content/developer/iota-101/objects/object-ownership/object-ownership.mdx similarity index 77% rename from docs/content/concepts/object-ownership.mdx rename to docs/content/developer/iota-101/objects/object-ownership/object-ownership.mdx index e0b320df619..9653e1a0127 100644 --- a/docs/content/concepts/object-ownership.mdx +++ b/docs/content/developer/iota-101/objects/object-ownership/object-ownership.mdx @@ -8,28 +8,28 @@ Every object has an owner field that dictates how you can use it in transactions An address-owned object is owned by a specific 32-byte address that is either an account address (derived from a particular signature scheme) or an object ID. An address-owned object is accessible only to its owner and no others. -Go to [Address-Owned Objects](./object-ownership/address-owned.mdx). +Go to [Address-Owned Objects](address-owned.mdx). ## Dynamic fields Dynamic fields and dynamic object fields on IOTA are added and removed dynamically, affect gas only when accessed, and store heterogeneous values. -Go to [Dynamic (Object) Fields](./dynamic-fields.mdx). +Go to [Dynamic (Object) Fields](../dynamic-fields/dynamic-fields.mdx). ## Immutable An immutable object is an object that can't be mutated, transferred, or deleted. Immutable objects have no owner, so anyone can use them. -Go to [Immutable Objects](./object-ownership/immutable.mdx). +Go to [Immutable Objects](immutable.mdx). ## Shared A shared object is an object that is shared using the `0x2::transfer::share_object` function and is accessible to everyone. Unlike owned objects, anyone can access shared ones on the network. -Go to [Shared Objects](./object-ownership/shared.mdx). +Go to [Shared Objects](shared.mdx). ## Wrapped In Move, you can organize data structures by putting a field of `struct` type in another. -Go to [Wrapped Objects](./object-ownership/wrapped.mdx). \ No newline at end of file +Go to [Wrapped Objects](wrapped.mdx). \ No newline at end of file diff --git a/docs/content/concepts/object-ownership/shared.mdx b/docs/content/developer/iota-101/objects/object-ownership/shared.mdx similarity index 100% rename from docs/content/concepts/object-ownership/shared.mdx rename to docs/content/developer/iota-101/objects/object-ownership/shared.mdx diff --git a/docs/content/concepts/object-ownership/wrapped.mdx b/docs/content/developer/iota-101/objects/object-ownership/wrapped.mdx similarity index 100% rename from docs/content/concepts/object-ownership/wrapped.mdx rename to docs/content/developer/iota-101/objects/object-ownership/wrapped.mdx diff --git a/docs/content/guides/developer/iota-101/shared-owned.mdx b/docs/content/developer/iota-101/objects/shared-owned.mdx similarity index 99% rename from docs/content/guides/developer/iota-101/shared-owned.mdx rename to docs/content/developer/iota-101/objects/shared-owned.mdx index e485a335509..f94938e6ffb 100644 --- a/docs/content/guides/developer/iota-101/shared-owned.mdx +++ b/docs/content/developer/iota-101/objects/shared-owned.mdx @@ -13,7 +13,7 @@ Transactions that access multiple shared objects, or particularly popular object To summarize, applications that are extremely sensitive to latency or gas costs, that do not need to handle complex multi-party transactions, or that already require an off-chain service could benefit from a design that only uses owned objects. Applications that require coordination between multiple parties will likely benefit from using shared objects. -For more information on the types of objects that IOTA supports, see [Object Ownership](/concepts/object-ownership.mdx). +For more information on the types of objects that IOTA supports, see [Object Ownership](object-ownership/object-ownership.mdx). ## Example: Escrow diff --git a/docs/content/concepts/transfers/custom-rules.mdx b/docs/content/developer/iota-101/objects/transfers/custom-rules.mdx similarity index 100% rename from docs/content/concepts/transfers/custom-rules.mdx rename to docs/content/developer/iota-101/objects/transfers/custom-rules.mdx diff --git a/docs/content/concepts/transfers/transfer-to-object.mdx b/docs/content/developer/iota-101/objects/transfers/transfer-to-object.mdx similarity index 97% rename from docs/content/concepts/transfers/transfer-to-object.mdx rename to docs/content/developer/iota-101/objects/transfers/transfer-to-object.mdx index 5ce18a7f23a..778558705fa 100644 --- a/docs/content/concepts/transfers/transfer-to-object.mdx +++ b/docs/content/developer/iota-101/objects/transfers/transfer-to-object.mdx @@ -105,7 +105,7 @@ Because `iota::transfer::Receiving` has only the `drop` ability, the existence o ## Custom receiving rules -Just like with [custom transfer policies](./custom-rules.mdx), IOTA allows for the definition of custom receivership rules for `key`-only objects. In particular, you can use the `iota::transfer::receive` function only on objects defined in the same module as the call to `iota::transfer::receive`--just like you can use the `iota::transfer::transfer` function only on objects defined in the module where it's being used. +Just like with [custom transfer policies](custom-rules.mdx), IOTA allows for the definition of custom receivership rules for `key`-only objects. In particular, you can use the `iota::transfer::receive` function only on objects defined in the same module as the call to `iota::transfer::receive`--just like you can use the `iota::transfer::transfer` function only on objects defined in the module where it's being used. Similarly for objects that also have the `store` ability, anyone can use the `iota::transfer::public_receive` function to receive them--just like `iota::transfer::public_transfer` can transfer any objects that have the `store` ability on them. diff --git a/docs/content/concepts/transfers.mdx b/docs/content/developer/iota-101/objects/transfers/transfers.mdx similarity index 88% rename from docs/content/concepts/transfers.mdx rename to docs/content/developer/iota-101/objects/transfers/transfers.mdx index 96d1299703c..7bde653527b 100644 --- a/docs/content/concepts/transfers.mdx +++ b/docs/content/developer/iota-101/objects/transfers/transfers.mdx @@ -8,10 +8,10 @@ Everything on IOTA is an object and your smart contracts are inevitably going to On IOTA, you can create custom transfer rules for objects that define the conditions that must be met for a valid transfer operation. The object you want to create custom transfer rules for cannot have the `store` ability, as that ability enables unrestricted transfers for the type via `iota::transfer::public_transfer` or the `TransferObjects` transaction command. -Go to [Custom Transfer Rules](./transfers/custom-rules.mdx). +Go to [Custom Transfer Rules](custom-rules.mdx). ## Transfer to Object On IOTA, you are not limited to only transferring objects to an address. You can transfer an object to another object, where the receiving object provides access control to the received object. -Go to [Transfer to Object](./transfers/transfer-to-object.mdx). \ No newline at end of file +Go to [Transfer to Object](transfer-to-object.mdx). \ No newline at end of file diff --git a/docs/content/concepts/versioning.mdx b/docs/content/developer/iota-101/objects/versioning.mdx similarity index 100% rename from docs/content/concepts/versioning.mdx rename to docs/content/developer/iota-101/objects/versioning.mdx diff --git a/docs/content/concepts/transactions/gas-smashing.mdx b/docs/content/developer/iota-101/transactions/gas-smashing.mdx similarity index 100% rename from docs/content/concepts/transactions/gas-smashing.mdx rename to docs/content/developer/iota-101/transactions/gas-smashing.mdx diff --git a/docs/content/guides/developer/iota-101/building-ptb.mdx b/docs/content/developer/iota-101/transactions/ptb/building-ptb.mdx similarity index 97% rename from docs/content/guides/developer/iota-101/building-ptb.mdx rename to docs/content/developer/iota-101/transactions/ptb/building-ptb.mdx index 5cea33dee35..36e9bb926b9 100644 --- a/docs/content/guides/developer/iota-101/building-ptb.mdx +++ b/docs/content/developer/iota-101/transactions/ptb/building-ptb.mdx @@ -3,7 +3,7 @@ title: Building Programmable Transaction Blocks description: Using the IOTA TypeScript SDK, you can create programmable transaction blocks to perform multiple commands in a single transaction. --- -This guide explores creating a programmable transaction block (PTB) on IOTA using the TypeScript SDK. For an overview of what a PTB is, see [Programmable Transaction Blocks](/concepts/transactions/prog-txn-blocks.mdx) in the Concepts section. If you don't already have the IOTA TypeScript SDK, follow the [install instructions](https://sdk.mystenlabs.com/typescript/install) on the IOTA TypeScript SDK site. +This guide explores creating a programmable transaction block (PTB) on IOTA using the TypeScript SDK. For an overview of what a PTB is, see [Programmable Transaction Blocks](prog-txn-blocks.mdx) in the Concepts section. If you don't already have the IOTA TypeScript SDK, follow the [install instructions](https://sdk.mystenlabs.com/typescript/install) on the IOTA TypeScript SDK site. This example starts by constructing a PTB to send IOTA. If you are familiar with the legacy IOTA transaction types, this is similar to a `payIOTA` transaction. To construct transactions, import the `TransactionBlock` class, and construct it: diff --git a/docs/content/guides/developer/iota-101/coin-mgt.mdx b/docs/content/developer/iota-101/transactions/ptb/coin-mgt.mdx similarity index 89% rename from docs/content/guides/developer/iota-101/coin-mgt.mdx rename to docs/content/developer/iota-101/transactions/ptb/coin-mgt.mdx index f83144d2f67..a17cedbc96e 100644 --- a/docs/content/guides/developer/iota-101/coin-mgt.mdx +++ b/docs/content/developer/iota-101/transactions/ptb/coin-mgt.mdx @@ -9,7 +9,7 @@ Because IOTA uses owned objects instead of a balance, it is common to own a numb ## SDK usage -The IOTA SDKs ([TypeScript](https://sdk.mystenlabs.com/typescript) and [Rust](/references/rust-sdk.mdx)) manage coins on your behalf, removing the overhead of having to deal with coin management manually. The SDKs attempt to merge coins whenever possible and assume that transactions are executed in sequence. That's a reasonable assumption with wallet-based transactions and for common scenarios in general. IOTA recommends relying on this feature if you do not have a need for heavy parallel or concurrent execution. +The IOTA SDKs ([TypeScript](https://sdk.mystenlabs.com/typescript) and [Rust](../../../../references/rust-sdk.mdx)) manage coins on your behalf, removing the overhead of having to deal with coin management manually. The SDKs attempt to merge coins whenever possible and assume that transactions are executed in sequence. That's a reasonable assumption with wallet-based transactions and for common scenarios in general. IOTA recommends relying on this feature if you do not have a need for heavy parallel or concurrent execution. ## Gas Smashing @@ -17,7 +17,7 @@ When executing a transaction IOTA allows you to provide a number of coins as pay Basically, you can provide as many coins as you want (with a max limit defined in the protocol configuration) and have all of them merged (smashed) into the first coin provided as payment. That coin, minus the gas budget, is then available inside the transaction and can be used in any command. If the coin is unused it is returned to the user. -Gas smashing is an important feature - and a key concept to understand - to have for the optimal management of coins. See [Gas Smashing](/concepts/transactions/gas-smashing.mdx) for more details. +Gas smashing is an important feature - and a key concept to understand - to have for the optimal management of coins. See [Gas Smashing](../gas-smashing.mdx) for more details. ## Generic coins diff --git a/docs/content/concepts/transactions/prog-txn-blocks.mdx b/docs/content/developer/iota-101/transactions/ptb/prog-txn-blocks.mdx similarity index 99% rename from docs/content/concepts/transactions/prog-txn-blocks.mdx rename to docs/content/developer/iota-101/transactions/ptb/prog-txn-blocks.mdx index 2d300b0aa7b..844f3f9b656 100644 --- a/docs/content/concepts/transactions/prog-txn-blocks.mdx +++ b/docs/content/developer/iota-101/transactions/ptb/prog-txn-blocks.mdx @@ -11,8 +11,8 @@ A PTB can perform up to 1,024 unique operations in a single execution, whereas t The remainder of this topic covers the semantics of the execution of the transaction commands. It assumes familiarity with the IOTA object model and the Move language. For more information on those topics, see the following documents: -- [Object model](../object-model.mdx) -- [Move Concepts](../iota-move-concepts.mdx) +- [Object model](../../objects/object-model.mdx) +- [Move Concepts](../../iota-move-concepts/iota-move-concepts.mdx) ## Transaction type @@ -46,7 +46,7 @@ The inputs and results can be seen as populating an array of values. For inputs, Input arguments to a PTB are broadly categorized as either objects or pure values. The direct implementation of these arguments is often obscured by transaction builders or SDKs. This section describes information or data the IOTA network needs when specifying the list of inputs, `[Input]`. Each `Input` is either an object, `Input::Object(ObjectArg)`, which contains the necessary metadata to specify to object being used, or a pure value, `Input::Pure(PureArg)`, which contains the bytes of the value. -For object inputs, the metadata needed differs depending on the type of [ownership of the object](../object-ownership.mdx). The data for the `ObjectArg` enum follows: +For object inputs, the metadata needed differs depending on the type of [ownership of the object](../../objects/object-ownership/object-ownership.mdx). The data for the `ObjectArg` enum follows: If the object is owned by an address (or it is immutable), then use `ObjectArg::ImmOrOwnedObject(ObjectID, SequenceNumber, ObjectDigest)`. The triple respectively specifies the object's ID, its sequence number (also known as its version), and the digest of the object's data. @@ -218,7 +218,7 @@ The `Package: ObjectID` is the Object ID of the package being upgraded. The pack The `UpgradeTicket: iota::package::UpgradeTicket` is the upgrade ticket for the package being upgraded and is generated from the `iota::package::UpgradeCap`. The ticket is taken by value (moved). -The command produces a single result type `iota::package::UpgradeReceipt` which provides proof for that upgrade. For more details on upgrades, see [Upgrading Packages](../iota-move-concepts/packages/upgrade.mdx). +The command produces a single result type `iota::package::UpgradeReceipt` which provides proof for that upgrade. For more details on upgrades, see [Upgrading Packages](../../iota-move-concepts/packages/upgrade.mdx). ### End of execution diff --git a/docs/content/guides/developer/iota-101/simulating-refs.mdx b/docs/content/developer/iota-101/transactions/ptb/simulating-refs.mdx similarity index 94% rename from docs/content/guides/developer/iota-101/simulating-refs.mdx rename to docs/content/developer/iota-101/transactions/ptb/simulating-refs.mdx index 2b312a87058..09430c342fe 100644 --- a/docs/content/guides/developer/iota-101/simulating-refs.mdx +++ b/docs/content/developer/iota-101/transactions/ptb/simulating-refs.mdx @@ -17,7 +17,7 @@ Programmable transaction blocks (PTBs) do not currently allow the use of object ## The borrow module -The IOTA framework includes a [borrow](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/docs/borrow.md) module that offers a solution to the reference problem. The module provides access to an object by value but builds a model that makes it impossible to destroy, transfer, or wrap the object retrieved. The borrow module exposes a `Referent` object that wraps another object (the object you want to reference). The module uses the [hot potato pattern](/concepts/iota-move-concepts/patterns/hot-potato.mdx) (via a `Borrow` instance) to allow retrieval of the wrapped object by value. Within the same PTB, the module then forces the object to be returned to the `Referent`. The `Borrow` instance guarantees that the object returned is the same that was retrieved. +The IOTA framework includes a [borrow](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/docs/borrow.md) module that offers a solution to the reference problem. The module provides access to an object by value but builds a model that makes it impossible to destroy, transfer, or wrap the object retrieved. The borrow module exposes a `Referent` object that wraps another object (the object you want to reference). The module uses the [hot potato pattern](../../iota-move-concepts/patterns/hot-potato.mdx) (via a `Borrow` instance) to allow retrieval of the wrapped object by value. Within the same PTB, the module then forces the object to be returned to the `Referent`. The `Borrow` instance guarantees that the object returned is the same that was retrieved. As an example, consider the following module stub that exposes an object (`Asset`) and a function (`use_asset`) to use that object. diff --git a/docs/content/guides/developer/iota-101/working-with-ptbs.mdx b/docs/content/developer/iota-101/transactions/ptb/working-with-ptbs.mdx similarity index 50% rename from docs/content/guides/developer/iota-101/working-with-ptbs.mdx rename to docs/content/developer/iota-101/transactions/ptb/working-with-ptbs.mdx index 710fe6896e7..8503e6c6fec 100644 --- a/docs/content/guides/developer/iota-101/working-with-ptbs.mdx +++ b/docs/content/developer/iota-101/transactions/ptb/working-with-ptbs.mdx @@ -2,7 +2,7 @@ title: Working with Programmable Transaction Blocks --- -Programmable transaction blocks (PTBs) are key elements of the IOTA ecosystem. Understanding PTBs and using them correctly are key fundamentals to creating efficient and cost-effective smart contracts. See [Programmable Transaction Blocks](../../../concepts/transactions/prog-txn-blocks.mdx) to learn about the structure of PTBs on IOTA. +Programmable transaction blocks (PTBs) are key elements of the IOTA ecosystem. Understanding PTBs and using them correctly are key fundamentals to creating efficient and cost-effective smart contracts. See [Programmable Transaction Blocks](prog-txn-blocks.mdx) to learn about the structure of PTBs on IOTA. The topics in this section focus on effectively utilizing PTBs in your smart contracts. @@ -10,23 +10,23 @@ The topics in this section focus on effectively utilizing PTBs in your smart con To fully appreciate the possibilities PTBs offer, you must build them. Using tools like the [IOTA TypeScript SDK](https://sdk.mystenlabs.com/typescript), you can begin to understand the power and flexibility they provide. -Go to [Building Programmable Transaction Blocks](./building-ptb.mdx). +Go to [Building Programmable Transaction Blocks](building-ptb.mdx). ## Coin Management -`Coin` objects on IOTA are different than other blockchains in that they are [owned objects](../../../concepts/object-ownership/address-owned.mdx). Whether you need your smart contract to utilize IOTA for gas payments or deal with generic coins, understanding coin management is crucial. Smart contracts use common patterns to accept coins and the PTBs you create must provide the correct interface to those smart contracts to facilitate successful transactions. +`Coin` objects on IOTA are different than other blockchains in that they are [owned objects](../../objects/object-ownership/address-owned.mdx). Whether you need your smart contract to utilize IOTA for gas payments or deal with generic coins, understanding coin management is crucial. Smart contracts use common patterns to accept coins and the PTBs you create must provide the correct interface to those smart contracts to facilitate successful transactions. -Go to [Coin Management](./coin-mgt.mdx). +Go to [Coin Management](coin-mgt.mdx). ## Simulating References The [`borrow` module](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/docs/iota-framework/borrow.md) of the IOTA framework offers some features you can use when your PTBs use objects by reference. -Go to [Simulating References](./simulating-refs.mdx). +Go to [Simulating References](simulating-refs.mdx). ## Related links Review this content for a complete picture of PTBs on IOTA. -- [Programmable Transaction Blocks](../../../concepts/transactions/prog-txn-blocks.mdx): Conceptual overview of the PTB architecture. -- [Life of a Transaction](../../../concepts/iota-architecture/transaction-lifecycle.mdx): Discover the life of a transaction from inception to finality. \ No newline at end of file +- [Programmable Transaction Blocks](prog-txn-blocks.mdx): Conceptual overview of the PTB architecture. +- [Life of a Transaction](../../../../about-iota/iota-architecture/transaction-lifecycle.mdx): Discover the life of a transaction from inception to finality. \ No newline at end of file diff --git a/docs/content/guides/developer/iota-101/sign-and-send-txn.mdx b/docs/content/developer/iota-101/transactions/sign-and-send-txn.mdx similarity index 84% rename from docs/content/guides/developer/iota-101/sign-and-send-txn.mdx rename to docs/content/developer/iota-101/transactions/sign-and-send-txn.mdx index b4f47900c3c..5b3224d2fcd 100644 --- a/docs/content/guides/developer/iota-101/sign-and-send-txn.mdx +++ b/docs/content/developer/iota-101/transactions/sign-and-send-txn.mdx @@ -4,13 +4,13 @@ title: Signing and Sending Transactions Transactions in IOTA represent calls to specific functionality (like calling a smart contract function) that execute on inputs to define the result of the transaction. -Inputs can either be an object reference (either to an owned object, an immutable object, or a shared object), or an encoded value (for example, a vector of bytes used as an argument to a Move call). After a transaction is constructed, usually through using [programmable transaction blocks](./building-ptb) (PTBs), the user signs the transaction and submits it to be executed on chain. +Inputs can either be an object reference (either to an owned object, an immutable object, or a shared object), or an encoded value (for example, a vector of bytes used as an argument to a Move call). After a transaction is constructed, usually through using [programmable transaction blocks](ptb/building-ptb.mdx) (PTBs), the user signs the transaction and submits it to be executed on chain. The signature is provided with the private key owned by the wallet, and its public key must be consistent with the transaction sender's IOTA address. IOTA uses a `IOTAKeyPair` to produce the signature, which commits to the Blake2b hash digest of the intent message (`intent || bcs bytes of tx_data`). The signature schemes currently supported are `Ed25519 Pure`, `ECDSA Secp256k1`, `ECDSA Secp256r1`, `Multisig`, and `zkLogin`. -You can instantiate `Ed25519 Pure`, `ECDSA Secp256k1`, and `ECDSA Secp256r1` using `IOTAKeyPair` and use it to sign transactions. Note that this guide does not apply to `Multisig` and `zkLogin`, please refer to their own pages ([Multisig](/concepts/cryptography/transaction-auth/multisig) and [zkLogin](https://docs.iota.io/concepts/cryptography/zklogin) respectively) for instructions. +You can instantiate `Ed25519 Pure`, `ECDSA Secp256k1`, and `ECDSA Secp256r1` using `IOTAKeyPair` and use it to sign transactions. Note that this guide does not apply to `Multisig` and `zkLogin`, please refer to their own pages ([Multisig](../../cryptography/explanations/transaction-auth/multisig.mdx) and [zkLogin](https://docs.iota.io../cryptography/explanations/zklogin) respectively) for instructions. With a signature and the transaction bytes, a transaction can be submitted to be executed. @@ -18,14 +18,14 @@ With a signature and the transaction bytes, a transaction can be submitted to be The following high-level process describes the overall workflow for constructing, signing and executing an on-chain transaction: -- Construct the transaction data by creating a `TransactionBlock` where multiple transactions are chained. See [Building Programmable Transaction Blocks](./building-ptb.mdx) for more information. +- Construct the transaction data by creating a `TransactionBlock` where multiple transactions are chained. See [Building Programmable Transaction Blocks](ptb/building-ptb.mdx) for more information. - The SDK's built-in gas estimation and coin selection picks the gas coin. -- Sign the transaction to generate a [signature](/concepts/cryptography/transaction-auth/signatures#user-signature). +- Sign the transaction to generate a [signature](../../cryptography/explanations/transaction-auth/signatures.mdx). - Submit the `TransactionBlock` and its signature for on-chain execution. :::info -If you want to use a specific gas coin, first find the gas coin object ID to be used to pay for gas, and explicitly use that in the PTB. If there is no gas coin object, use the [splitCoin](./building-ptb#available-transactions) transaction to create a gas coin object. The split coin transaction should be the first transaction call in the PTB. +If you want to use a specific gas coin, first find the gas coin object ID to be used to pay for gas, and explicitly use that in the PTB. If there is no gas coin object, use the [splitCoin](ptb/building-ptb.mdx#available-transactions) transaction to create a gas coin object. The split coin transaction should be the first transaction call in the PTB. ::: @@ -62,7 +62,7 @@ const kp_import_2 = Secp256r1Keypair.fromSecretKey( fromHex('0xd463e11c7915945e86ac2b72d88b8190cfad8ff7b48e7eb892c275a5cf0a3e82'), ); -// $MNEMONICS refers to 12/15/18/21/24 words from the wordlist, e.g. "retire skin goose will hurry this field stadium drastic label husband venture cruel toe wire". Refer to [Keys and Addresses](/concepts/cryptography/transaction-auth/keys-addresses.mdx) for more. +// $MNEMONICS refers to 12/15/18/21/24 words from the wordlist, e.g. "retire skin goose will hurry this field stadium drastic label husband venture cruel toe wire". Refer to [Keys and Addresses](../cryptography/explanations/transaction-auth/keys-addresses.mdx) for more. const kp_derive_0 = Ed25519Keypair.deriveKeypair('$MNEMONICS'); const kp_derive_1 = Secp256k1Keypair.deriveKeypair('$MNEMONICS'); const kp_derive_2 = Secp256r1Keypair.deriveKeypair('$MNEMONICS'); @@ -151,7 +151,7 @@ There are various ways to instantiate a `IOTAKeyPair` and to derive its public k let sender = IOTAAddress::from(&pk); ``` -Next, sign transaction data constructed using an example programmable transaction block with default gas coin, gas budget, and gas price. See [Building Programmable Transaction Blocks](./building-ptb.mdx) for more information. +Next, sign transaction data constructed using an example programmable transaction block with default gas coin, gas budget, and gas price. See [Building Programmable Transaction Blocks](ptb/building-ptb.mdx) for more information. ```rust // construct an example programmable transaction. @@ -217,7 +217,7 @@ Finally, submit the transaction with the signature. -When using the [IOTA CLI](/references/cli.mdx) for the first time, it creates a local file in `~/.iota/keystore` on your machine with a list of private keys (encoded as Base64 encoded `flag || 32-byte-private-key`). You can use any key to sign transactions by specifying its address. Use `iota keytool list` to see a list of addresses. +When using the [IOTA CLI](../../../references/cli.mdx) for the first time, it creates a local file in `~/.iota/keystore` on your machine with a list of private keys (encoded as Base64 encoded `flag || 32-byte-private-key`). You can use any key to sign transactions by specifying its address. Use `iota keytool list` to see a list of addresses. There are three ways to initialize a key: @@ -233,14 +233,14 @@ iota keytool import "0xd463e11c7915945e86ac2b72d88b8190cfad8ff7b48e7eb892c275a5c iota keytool import "0xd463e11c7915945e86ac2b72d88b8190cfad8ff7b48e7eb892c275a5cf0a3e82" secp256r1 # import the mnemonics (recovery phrase) with derivation path to keystore. -# $MNEMONICS refers to 12/15/18/21/24 words from the wordlist, e.g. "retire skin goose will hurry this field stadium drastic label husband venture cruel toe wire". Refer to [Keys and Addresses](/concepts/cryptography/transaction-auth/keys-addresses.mdx) for more. +# $MNEMONICS refers to 12/15/18/21/24 words from the wordlist, e.g. "retire skin goose will hurry this field stadium drastic label husband venture cruel toe wire". Refer to [Keys and Addresses](../cryptography/explanations/transaction-auth/keys-addresses.mdx) for more. iota keytool import "$MNEMONICS" ed25519 iota keytool import "$MNEMONICS" secp256k1 iota keytool import "$MNEMONICS" secp256r1 ``` -Create a transfer transaction in CLI. Set the $IOTA_ADDRESS to the one corresponding to the keypair used to sign. $GAS_COIN_ID refers to the object ID that is owned by the sender to be used as gas. $GAS_BUDGET refers to the budget used to execute transaction. Then sign with the private key corresponding to the sender address. $MNEMONICS refers to 12/15/18/21/24 words from the wordlist, e.g. "retire skin goose will hurry this field stadium drastic label husband venture cruel toe wire". Refer to [Keys and Addresses](/concepts/cryptography/transaction-auth/keys-addresses.mdx) for more. +Create a transfer transaction in CLI. Set the $IOTA_ADDRESS to the one corresponding to the keypair used to sign. $GAS_COIN_ID refers to the object ID that is owned by the sender to be used as gas. $GAS_BUDGET refers to the budget used to execute transaction. Then sign with the private key corresponding to the sender address. $MNEMONICS refers to 12/15/18/21/24 words from the wordlist, e.g. "retire skin goose will hurry this field stadium drastic label husband venture cruel toe wire". Refer to [Keys and Addresses](../../cryptography/explanations/transaction-auth/keys-addresses.mdx) for more. ```shell iota client gas @@ -254,8 +254,8 @@ iota client execute-signed-tx --tx-bytes $TX_BYTES --signatures $SERIALIZED_SIGN ### Notes -1. This guide demonstrates how to sign with a single private key. Refer to [Multisig](/concepts/cryptography/transaction-auth/multisig.mdx) when it is preferred to set up more complex signing policies. -2. Similarly, native zkLogin does not follow the above steps, see [the docs](/concepts/cryptography/zklogin.mdx) to understand how to derive a zkLogin address, and produce a zkLogin signature with an ephemeral key pair. -3. If you decide to implement your own signing mechanisms instead of using the previous tools, see the [Signatures](/concepts/cryptography/transaction-auth/signatures.mdx) doc on the accepted signature specifications for each scheme. -4. Flag is one byte that differentiates signature schemes. See supported schemes and its flag in [Signatures](/concepts/cryptography/transaction-auth/signatures.mdx). -5. The `execute_transaction_block` endpoint takes a list of signatures, so it should contain exactly one user signature, unless you are using sponsored transaction that a second signature for the gas object can be provided. See [Sponsored Transactions](/concepts/transactions/sponsored-transactions.mdx) for more information. +1. This guide demonstrates how to sign with a single private key. Refer to [Multisig](../../cryptography/explanations/transaction-auth/multisig.mdx) when it is preferred to set up more complex signing policies. +2. Similarly, native zkLogin does not follow the above steps, see [the docs](../../cryptography/explanations/zklogin.mdx) to understand how to derive a zkLogin address, and produce a zkLogin signature with an ephemeral key pair. +3. If you decide to implement your own signing mechanisms instead of using the previous tools, see the [Signatures](../../cryptography/explanations/transaction-auth/signatures.mdx) doc on the accepted signature specifications for each scheme. +4. Flag is one byte that differentiates signature schemes. See supported schemes and its flag in [Signatures](../../cryptography/explanations/transaction-auth/signatures.mdx). +5. The `execute_transaction_block` endpoint takes a list of signatures, so it should contain exactly one user signature, unless you are using sponsored transaction that a second signature for the gas object can be provided. See [Sponsored Transactions](sponsored-transactions.mdx) for more information. diff --git a/docs/content/guides/developer/iota-101/sponsor-txn.mdx b/docs/content/developer/iota-101/transactions/sponsor-txn.mdx similarity index 100% rename from docs/content/guides/developer/iota-101/sponsor-txn.mdx rename to docs/content/developer/iota-101/transactions/sponsor-txn.mdx diff --git a/docs/content/concepts/transactions/sponsored-transactions.mdx b/docs/content/developer/iota-101/transactions/sponsored-transactions.mdx similarity index 98% rename from docs/content/concepts/transactions/sponsored-transactions.mdx rename to docs/content/developer/iota-101/transactions/sponsored-transactions.mdx index 90949e617cd..259832978cf 100644 --- a/docs/content/concepts/transactions/sponsored-transactions.mdx +++ b/docs/content/developer/iota-101/transactions/sponsored-transactions.mdx @@ -141,4 +141,4 @@ pub struct GasData { } ``` -To learn more about transactions in IOTA, see [Transactions](../transactions.mdx). +To learn more about transactions in IOTA, see [Transactions](transactions.mdx). diff --git a/docs/content/concepts/transactions.mdx b/docs/content/developer/iota-101/transactions/transactions.mdx similarity index 96% rename from docs/content/concepts/transactions.mdx rename to docs/content/developer/iota-101/transactions/transactions.mdx index 6ed3eedb3ae..48d05e1468a 100644 --- a/docs/content/concepts/transactions.mdx +++ b/docs/content/developer/iota-101/transactions/transactions.mdx @@ -4,14 +4,14 @@ title: Transactions All updates to the IOTA database happen via transactions. This topic describes the transaction types supported by IOTA and explains how their execution changes the ledger. There are only two kinds of transactions on IOTA: -- Programmable transaction blocks, which anyone can submit on the network. For information on these transactions, see [Programmable Transaction Blocks](./transactions/prog-txn-blocks.mdx). +- Programmable transaction blocks, which anyone can submit on the network. For information on these transactions, see [Programmable Transaction Blocks](ptb/prog-txn-blocks.mdx). - System transactions, which only validators can directly submit and are responsible for keeping the network running (changing epochs, starting checkpoints, and so on). ## Transaction metadata All IOTA transactions have the following common metadata: -- **Sender address:** The [address](guides/developer/getting-started/get-address.mdx) of the user sending this transaction. +- **Sender address:** The [address](../../getting-started/get-address.mdx) of the user sending this transaction. - **Gas input:** An object reference pointing to the object that will be used to pay for this transaction's execution and storage. This object must be owned by the user and must be of type `iota::coin::Coin` (i.e., the IOTA native currency). - **Gas price:** An unsigned integer specifying the number of native tokens per gas unit this transaction will pay. The gas price must always be nonzero. - **Maximum gas budget:** The maximum number of gas units that can be expended by executing this transaction. If this budget is exceeded, transaction execution will abort and have no effects other than debiting the gas input object. Consequently, the gas input object must have a value higher than the gas price multiplied by the max gas, and this product is the maximum amount that the gas input object will be debited for the transaction. diff --git a/docs/content/guides/developer/iota-101/using-events.mdx b/docs/content/developer/iota-101/using-events.mdx similarity index 100% rename from docs/content/guides/developer/iota-101/using-events.mdx rename to docs/content/developer/iota-101/using-events.mdx diff --git a/docs/content/standards/closed-loop-token.mdx b/docs/content/developer/standards/closed-loop-token.mdx similarity index 74% rename from docs/content/standards/closed-loop-token.mdx rename to docs/content/developer/standards/closed-loop-token.mdx index a4b2a0d32a1..d8a36fc16fe 100644 --- a/docs/content/standards/closed-loop-token.mdx +++ b/docs/content/developer/standards/closed-loop-token.mdx @@ -6,7 +6,7 @@ Using the Closed-Loop Token standard, you can limit the applications that can us ## Background and use cases -The [Coin standard](./coin.mdx) on IOTA is an example of an open-loop system - coins are free-flowing, [wrappable](/concepts/object-ownership/wrapped.mdx), [freely transferable](/concepts/transfers/custom-rules.mdx#the-store-ability-and-transfer-rules) and you can store them in any application. The best real world analogy would be cash - hardly regulated and can be freely used and passed. +The [Coin standard](coin.mdx) on IOTA is an example of an open-loop system - coins are free-flowing, [wrappable](../iota-101/objects/object-ownership/wrapped.mdx), [freely transferable](../iota-101/objects/transfers/custom-rules.mdx#the-store-ability-and-transfer-rules) and you can store them in any application. The best real world analogy would be cash - hardly regulated and can be freely used and passed. Some applications, however, require constraining the scope of the token to a specific purpose. For example, some applications might need a token that you can only use for a specific service, or that an authorized account can only use, or a token that you can block certain accounts from using. A real-world analogy would be a bank account - regulated, bank-controlled, and compliant with certain rules and policies. @@ -48,7 +48,7 @@ flowchart LR ``` -Unlike Coin, which has `key + store` abilities and thus supports wrapping and public transfers, Token has only the `key` ability and cannot be wrapped, stored as a dynamic field, or freely transferred (unless there's a custom policy for that). Due to this restriction, Token **can only be owned by an account** and can't be stored in an application (however, it can be "spent" - see [Spending section](./closed-loop-token/spending.mdx) section). +Unlike Coin, which has `key + store` abilities and thus supports wrapping and public transfers, Token has only the `key` ability and cannot be wrapped, stored as a dynamic field, or freely transferred (unless there's a custom policy for that). Due to this restriction, Token **can only be owned by an account** and can't be stored in an application (however, it can be "spent" - see [Spending section](closed-loop-token/spending.mdx) section). ```move // defined in `iota::coin` @@ -60,7 +60,7 @@ struct Token has key { id: UID, balance: Balance } ## Compliance and rules -You can set up any rules for transfers, spends, and conversions for the tokens you create. You specify these rules per action in the [TokenPolicy](./closed-loop-token/token-policy.mdx). [Rules](./closed-loop-token/rules.mdx) are custom programmable restrictions that you can use to implement any request authorization or validation logic. +You can set up any rules for transfers, spends, and conversions for the tokens you create. You specify these rules per action in the [TokenPolicy](closed-loop-token/token-policy.mdx). [Rules](closed-loop-token/rules.mdx) are custom programmable restrictions that you can use to implement any request authorization or validation logic. For example, a policy can set a limit on a transfer - `X` tokens per operation; or require user verification before spending tokens; or allow spending tokens only on a specific service. @@ -76,11 +76,11 @@ Tokens have a set of public and protected actions that you can use to manage the - `token::zero` - create an empty (zero balance) token - `token::destroy_zero` - destroy a token with zero balance -See [Coin Token Comparison](./closed-loop-token/coin-token-comparison.mdx) for coin and token methods comparison. +See [Coin Token Comparison](closed-loop-token/coin-token-comparison.mdx) for coin and token methods comparison. ## Protected actions -Protected actions are ones that issue an [`ActionRequest`](./closed-loop-token/action-request.mdx) - a hot-potato struct that must be resolved for the transaction to succeed. There are three main ways to resolve an `ActionRequest`, most common of which is via the [`TokenPolicy`](./closed-loop-token/token-policy.mdx). +Protected actions are ones that issue an [`ActionRequest`](closed-loop-token/action-request.mdx) - a hot-potato struct that must be resolved for the transaction to succeed. There are three main ways to resolve an `ActionRequest`, most common of which is via the [`TokenPolicy`](closed-loop-token/token-policy.mdx). - `token::transfer` - transfer a token to a specified address - `token::to_coin` - convert a token to a coin @@ -91,4 +91,4 @@ The previous methods are included in the base implementation, however it is poss ## Token policy and rules -Protected actions are disabled by default but you can enable them in a [`TokenPolicy`](./closed-loop-token/token-policy.mdx). Additionally, you can set custom restrictions called [rules](./closed-loop-token/rules.mdx) that a specific action must satisfy for it to succeed. +Protected actions are disabled by default but you can enable them in a [`TokenPolicy`](closed-loop-token/token-policy.mdx). Additionally, you can set custom restrictions called [rules](closed-loop-token/rules.mdx) that a specific action must satisfy for it to succeed. diff --git a/docs/content/standards/closed-loop-token/action-request.mdx b/docs/content/developer/standards/closed-loop-token/action-request.mdx similarity index 95% rename from docs/content/standards/closed-loop-token/action-request.mdx rename to docs/content/developer/standards/closed-loop-token/action-request.mdx index 924f0e315f3..9d7d2498313 100644 --- a/docs/content/standards/closed-loop-token/action-request.mdx +++ b/docs/content/developer/standards/closed-loop-token/action-request.mdx @@ -23,9 +23,9 @@ Tokens have four protected actions that create an `ActionRequest`: - `amount`: The amount of the token that is being transferred, spent, converted, and so on. - `sender`: The account that initiated the action. - `recipient`: The account that receives the token in `transfer` action (use for custom actions). -- `spent_balance`: The balance of a spent token in the [`spend` action](./spending.mdx) (use in custom actions). +- `spent_balance`: The balance of a spent token in the [`spend` action](spending.mdx) (use in custom actions). -Rules can use these fields to determine whether the action should be allowed or not. Rules are custom modules that implement restriction logic. See [Rules](./rules.mdx) for more details. +Rules can use these fields to determine whether the action should be allowed or not. Rules are custom modules that implement restriction logic. See [Rules](rules.mdx) for more details. An example of a function creating an `ActionRequest`: @@ -41,7 +41,7 @@ public fun transfer( There are three ways to confirm an `ActionRequest` using a: 1. `TreasuryCap` - you (or an application storing the `TreasuryCap`) can call the `token::confirm_with_treasury_cap` function to confirm any request. This method is useful for applications that store the `TreasuryCap` and implement custom logic; it also allows you to `mint` and `transfer` tokens, bypassing the restrictions. -2. [`TokenPolicy`](./token-policy.mdx) - create a shared `TokenPolicy` and set up allowed actions and requirements for each action. This way, applications or wallets know which actions are considered `public` and so they are able to perform them. +2. [`TokenPolicy`](token-policy.mdx) - create a shared `TokenPolicy` and set up allowed actions and requirements for each action. This way, applications or wallets know which actions are considered `public` and so they are able to perform them. 3. `TokenPolicyCap` - use the capability managing the `TokenPolicy` to confirm requests. This can be useful for applications that have the `TreasuryCap` wrapped and inaccessible; and you need to authorize some administrator action. :::info diff --git a/docs/content/standards/closed-loop-token/coin-token-comparison.mdx b/docs/content/developer/standards/closed-loop-token/coin-token-comparison.mdx similarity index 100% rename from docs/content/standards/closed-loop-token/coin-token-comparison.mdx rename to docs/content/developer/standards/closed-loop-token/coin-token-comparison.mdx diff --git a/docs/content/standards/closed-loop-token/rules.mdx b/docs/content/developer/standards/closed-loop-token/rules.mdx similarity index 88% rename from docs/content/standards/closed-loop-token/rules.mdx rename to docs/content/developer/standards/closed-loop-token/rules.mdx index d9c1511bc27..3fd38e46619 100644 --- a/docs/content/standards/closed-loop-token/rules.mdx +++ b/docs/content/developer/standards/closed-loop-token/rules.mdx @@ -2,7 +2,7 @@ title: Rules --- -Rules are programmable restrictions that you can apply to any action in the [`TokenPolicy`](./token-policy.mdx). They are the tool of compliance, regulation, and enforcement of certain business logic in the closed-loop system. +Rules are programmable restrictions that you can apply to any action in the [`TokenPolicy`](token-policy.mdx). They are the tool of compliance, regulation, and enforcement of certain business logic in the closed-loop system. ## Rule structure @@ -13,15 +13,15 @@ A rule is represented as a witness - a type with a `drop` ability. You can eithe struct Rule has drop {} ``` -After you [add a rule](./token-policy.mdx#adding-rules) to an action in the `TokenPolicy`, the action requires a stamp of the rule to pass confirmation. +After you [add a rule](token-policy.mdx#adding-rules) to an action in the `TokenPolicy`, the action requires a stamp of the rule to pass confirmation. -See the [Approving actions](./action-request.mdx#approving-actions) section for more details on how to approve an action. +See the [Approving actions](action-request.mdx#approving-actions) section for more details on how to approve an action. ## Modular rules You can publish rules as separate reusable modules. This enables you to create a library of rules that you can use in different token policies, maximizing code reuse and minimizing the risk of errors. -A rule module is a regular module with a `verify`-like function that typically takes a `TokenPolicy`, [`ActionRequest`](./action-request.mdx), and a `TxContext` as arguments. The function is responsible for verifying the action and stamping the `ActionRequest` with the rule type. +A rule module is a regular module with a `verify`-like function that typically takes a `TokenPolicy`, [`ActionRequest`](action-request.mdx), and a `TxContext` as arguments. The function is responsible for verifying the action and stamping the `ActionRequest` with the rule type. ```move module example::pass_rule { diff --git a/docs/content/standards/closed-loop-token/spending.mdx b/docs/content/developer/standards/closed-loop-token/spending.mdx similarity index 91% rename from docs/content/standards/closed-loop-token/spending.mdx rename to docs/content/developer/standards/closed-loop-token/spending.mdx index ab80eebeeb2..5d28ee32023 100644 --- a/docs/content/standards/closed-loop-token/spending.mdx +++ b/docs/content/developer/standards/closed-loop-token/spending.mdx @@ -2,7 +2,7 @@ title: Spending --- -Because `Token` types do not have the `store` ability, it is impossible to store them in another object. Hence, `Coin`-like approaches to spending are not possible - an application that takes `Token` as a payment won't be able to add it to its balance. To address this issue, `Token` has a `spend` method, which allows spending it in one application and then delivering it as a `spent_balance` to the [`TokenPolicy`](./token-policy.mdx) or burning right away with a `TreasuryCap`. +Because `Token` types do not have the `store` ability, it is impossible to store them in another object. Hence, `Coin`-like approaches to spending are not possible - an application that takes `Token` as a payment won't be able to add it to its balance. To address this issue, `Token` has a `spend` method, which allows spending it in one application and then delivering it as a `spent_balance` to the [`TokenPolicy`](token-policy.mdx) or burning right away with a `TreasuryCap`. ## Spend action @@ -13,7 +13,7 @@ Tokens can be spent by calling the `spend` method. It takes the following argume public fun spend(token: Token, ctx: &mut TxContext): ActionRequest; ``` -As the signature shows, the `Token` object is consumed. Its balance becomes the `spent_balance` in the [`ActionRequest`](./action-request.mdx#actionrequest-structure). +As the signature shows, the `Token` object is consumed. Its balance becomes the `spent_balance` in the [`ActionRequest`](action-request.mdx#actionrequest-structure). ## Spent token diff --git a/docs/content/standards/closed-loop-token/token-policy.mdx b/docs/content/developer/standards/closed-loop-token/token-policy.mdx similarity index 95% rename from docs/content/standards/closed-loop-token/token-policy.mdx rename to docs/content/developer/standards/closed-loop-token/token-policy.mdx index 124057d8b3b..0afc5483d1a 100644 --- a/docs/content/standards/closed-loop-token/token-policy.mdx +++ b/docs/content/developer/standards/closed-loop-token/token-policy.mdx @@ -20,7 +20,7 @@ You must use the `token::share_policy` function to share the `TokenPolicy` objec ## Allow and disallow -To allow methods without any conditions, use the `token::allow` function. The function takes a `TokenPolicy` and `TokenPolicyCap` as arguments. If allowed, the action can be confirmed in the `TokenPolicy` using the `token::confirm_request` function (see [`ActionRequest`](./action-request.mdx#confirming-with-tokenpolicy)). +To allow methods without any conditions, use the `token::allow` function. The function takes a `TokenPolicy` and `TokenPolicyCap` as arguments. If allowed, the action can be confirmed in the `TokenPolicy` using the `token::confirm_request` function (see [`ActionRequest`](action-request.mdx#confirming-with-tokenpolicy)). ```move // module iota::token @@ -36,7 +36,7 @@ Similarly, you can use the `token::disallow` function to completely disable an a ## Adding rules -`TokenPolicy` can specify custom conditions for each action. These conditions are called rules and are typically implemented as separate Move modules. The identifier of the rule is its type. See [Rules](./rules.mdx) for more information. +`TokenPolicy` can specify custom conditions for each action. These conditions are called rules and are typically implemented as separate Move modules. The identifier of the rule is its type. See [Rules](rules.mdx) for more information. The pseudo-code structure of the `TokenPolicy` is as follows. Each action can have multiple rules associated with it. @@ -91,4 +91,4 @@ public fun flush( | remove_rule_for_action | Remove a rule for an action in the `TokenPolicy` | | confirm_request | Confirm an `ActionRequest` with a `TokenPolicy` | | confirm_request_mut | Similar to `confirm_request` but only works for `spend` action | -| flush | Flush the spent balance from the `TokenPolicy` (see [Spending](./spending.mdx)) | +| flush | Flush the spent balance from the `TokenPolicy` (see [Spending](spending.mdx)) | diff --git a/docs/content/standards/coin.mdx b/docs/content/developer/standards/coin.mdx similarity index 95% rename from docs/content/standards/coin.mdx rename to docs/content/developer/standards/coin.mdx index 3f5904dd9d6..b97965fe8e4 100644 --- a/docs/content/standards/coin.mdx +++ b/docs/content/developer/standards/coin.mdx @@ -6,7 +6,7 @@ sidebar_label: Coin The Coin standard is the technical standard used for smart contracts on IOTA for creating coins on the IOTA blockchain. The standardization of coin creation on IOTA means that wallets, exchanges, and other smart contracts can manage coins created on IOTA the same as they manage IOTA, without any additional processing logic. -See [IOTA Tokenomics](../concepts/tokenomics.mdx) to learn more about the IOTA native coin and its use on the IOTA network. +See [IOTA Tokenomics](../../about-iota/tokenomics.mdx) to learn more about the IOTA native coin and its use on the IOTA network. Although coins on IOTA follow the Coin standard, they can offer specialized abilities. For example, you can create a regulated token that allows its creator to add specific addresses to a deny list, so that the identified addresses cannot use the token as inputs to transactions. @@ -18,7 +18,7 @@ In the IOTA blockchain ecosystem, the `Coin` type represents open-loop fungib :::info -The documentation refers to fungible tokens created on IOTA using the Coin standard as "coins". For fungible tokens created on IOTA using the [Closed-Loop Token standard](./closed-loop-token.mdx), the documentation uses the term "tokens". In practice, the terms for both these objects are often interchangeable. +The documentation refers to fungible tokens created on IOTA using the Coin standard as "coins". For fungible tokens created on IOTA using the [Closed-Loop Token standard](closed-loop-token.mdx), the documentation uses the term "tokens". In practice, the terms for both these objects are often interchangeable. ::: @@ -264,8 +264,8 @@ public entry fun ( Check out the following content for more information about coins and tokens on IOTA: -- [Create a Coin](../guides/developer/iota-101/create-coin.mdx): Guide for creating coins and regulated coins in your smart contracts. -- [Closed-Loop Token Standard](./closed-loop-token.mdx): Details the Token standard on IOTA. +- [Create a Coin](../iota-101/create-coin/create-coin.mdx): Guide for creating coins and regulated coins in your smart contracts. +- [Closed-Loop Token Standard](closed-loop-token.mdx): Details the Token standard on IOTA. - [`coin` module rustdoc documentation](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/docs/iota-framework/coin.md): Automated documentation output for the IOTA framework `coin` module. - [`token` module rustdoc documentation](https://github.com/iotaledger/iota/blob/main/crates/iota-framework/docs/iota-framework/token.md): Automated documentation output for the IOTA framework `token` module. -- [Tokenomics](../concepts/tokenomics.mdx): Discover the IOTA ecosystem and where IOTA coins fit within it. \ No newline at end of file +- [Tokenomics](../../about-iota/tokenomics.mdx): Discover the IOTA ecosystem and where IOTA coins fit within it. \ No newline at end of file diff --git a/docs/content/standards/deepbook.mdx b/docs/content/developer/standards/deepbook.mdx similarity index 100% rename from docs/content/standards/deepbook.mdx rename to docs/content/developer/standards/deepbook.mdx diff --git a/docs/content/standards/deepbook/design.mdx b/docs/content/developer/standards/deepbook/design.mdx similarity index 100% rename from docs/content/standards/deepbook/design.mdx rename to docs/content/developer/standards/deepbook/design.mdx diff --git a/docs/content/standards/deepbook/orders.mdx b/docs/content/developer/standards/deepbook/orders.mdx similarity index 100% rename from docs/content/standards/deepbook/orders.mdx rename to docs/content/developer/standards/deepbook/orders.mdx diff --git a/docs/content/standards/deepbook/pools.mdx b/docs/content/developer/standards/deepbook/pools.mdx similarity index 100% rename from docs/content/standards/deepbook/pools.mdx rename to docs/content/developer/standards/deepbook/pools.mdx diff --git a/docs/content/standards/deepbook/query-the-pool.mdx b/docs/content/developer/standards/deepbook/query-the-pool.mdx similarity index 100% rename from docs/content/standards/deepbook/query-the-pool.mdx rename to docs/content/developer/standards/deepbook/query-the-pool.mdx diff --git a/docs/content/standards/deepbook/routing-a-swap.mdx b/docs/content/developer/standards/deepbook/routing-a-swap.mdx similarity index 100% rename from docs/content/standards/deepbook/routing-a-swap.mdx rename to docs/content/developer/standards/deepbook/routing-a-swap.mdx diff --git a/docs/content/standards/deepbook/trade-and-swap.mdx b/docs/content/developer/standards/deepbook/trade-and-swap.mdx similarity index 100% rename from docs/content/standards/deepbook/trade-and-swap.mdx rename to docs/content/developer/standards/deepbook/trade-and-swap.mdx diff --git a/docs/content/standards/display.mdx b/docs/content/developer/standards/display.mdx similarity index 100% rename from docs/content/standards/display.mdx rename to docs/content/developer/standards/display.mdx diff --git a/docs/content/standards/images/balance-token-coin.png b/docs/content/developer/standards/images/balance-token-coin.png similarity index 100% rename from docs/content/standards/images/balance-token-coin.png rename to docs/content/developer/standards/images/balance-token-coin.png diff --git a/docs/content/standards/kiosk-apps.mdx b/docs/content/developer/standards/kiosk-apps.mdx similarity index 95% rename from docs/content/standards/kiosk-apps.mdx rename to docs/content/developer/standards/kiosk-apps.mdx index 8cbb75e1acc..80b35913dc7 100644 --- a/docs/content/standards/kiosk-apps.mdx +++ b/docs/content/developer/standards/kiosk-apps.mdx @@ -8,7 +8,7 @@ Kiosk apps are a way to extend the functionality of IOTA Kiosk while keeping the There are two types of apps: - [Basic apps](#basic-apps) -- [Permissioned apps](#permissioned-apps) +- [Permissioned apps](#permissioned-apps-using-the-kiosk-apps-api-permissioned-apps) ## Basic apps @@ -188,7 +188,7 @@ Use the `can_place(kiosk: &Kiosk): bool` function to check if the app has t ## App storage -Every app gets its isolated storage as a [bag type](../concepts/dynamic-fields/tables-bags.mdx) that only the app module can access (providing the app witness). After you install an app, it can use the storage to store its data. Ideally, the storage should be managed in a way that allows the app to be removed from the kiosk if there are no active trades or other activities happening at the moment. +Every app gets its isolated storage as a [bag type](../iota-101/objects/dynamic-fields/tables-bags.mdx) that only the app module can access (providing the app witness). After you install an app, it can use the storage to store its data. Ideally, the storage should be managed in a way that allows the app to be removed from the kiosk if there are no active trades or other activities happening at the moment. The storage is always available to the app if it is installed. The owner of a kiosk can't access the storage of the app if the logic for it is not implemented. diff --git a/docs/content/standards/kiosk.mdx b/docs/content/developer/standards/kiosk.mdx similarity index 100% rename from docs/content/standards/kiosk.mdx rename to docs/content/developer/standards/kiosk.mdx diff --git a/docs/content/standards.mdx b/docs/content/developer/standards/standards.mdx similarity index 100% rename from docs/content/standards.mdx rename to docs/content/developer/standards/standards.mdx diff --git a/docs/content/standards/wallet-standard.mdx b/docs/content/developer/standards/wallet-standard.mdx similarity index 100% rename from docs/content/standards/wallet-standard.mdx rename to docs/content/developer/standards/wallet-standard.mdx diff --git a/docs/content/guides/stardust/addresses.mdx b/docs/content/developer/stardust/addresses.mdx similarity index 100% rename from docs/content/guides/stardust/addresses.mdx rename to docs/content/developer/stardust/addresses.mdx diff --git a/docs/content/guides/stardust/claiming.mdx b/docs/content/developer/stardust/claiming.mdx similarity index 100% rename from docs/content/guides/stardust/claiming.mdx rename to docs/content/developer/stardust/claiming.mdx diff --git a/docs/content/guides/stardust/faq.mdx b/docs/content/developer/stardust/faq.mdx similarity index 100% rename from docs/content/guides/stardust/faq.mdx rename to docs/content/developer/stardust/faq.mdx diff --git a/docs/content/guides/stardust/if-tools.mdx b/docs/content/developer/stardust/if-tools.mdx similarity index 100% rename from docs/content/guides/stardust/if-tools.mdx rename to docs/content/developer/stardust/if-tools.mdx diff --git a/docs/content/guides/stardust/migration-process.mdx b/docs/content/developer/stardust/migration-process.mdx similarity index 100% rename from docs/content/guides/stardust/migration-process.mdx rename to docs/content/developer/stardust/migration-process.mdx diff --git a/docs/content/guides/stardust/move-models.mdx b/docs/content/developer/stardust/move-models.mdx similarity index 100% rename from docs/content/guides/stardust/move-models.mdx rename to docs/content/developer/stardust/move-models.mdx diff --git a/docs/content/guides/stardust/testing.mdx b/docs/content/developer/stardust/testing.mdx similarity index 100% rename from docs/content/guides/stardust/testing.mdx rename to docs/content/developer/stardust/testing.mdx diff --git a/docs/content/guides/stardust/units.mdx b/docs/content/developer/stardust/units.mdx similarity index 100% rename from docs/content/guides/stardust/units.mdx rename to docs/content/developer/stardust/units.mdx diff --git a/docs/content/guides/stardust/vested.mdx b/docs/content/developer/stardust/vested.mdx similarity index 100% rename from docs/content/guides/stardust/vested.mdx rename to docs/content/developer/stardust/vested.mdx diff --git a/docs/content/guides/developer/advanced/efficient-smart-contracts.mdx b/docs/content/guides/developer/advanced/efficient-smart-contracts.mdx deleted file mode 100644 index 7ddb0c9458f..00000000000 --- a/docs/content/guides/developer/advanced/efficient-smart-contracts.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Efficient Smart Contracts -draft: true ---- - -Content coming soon \ No newline at end of file diff --git a/docs/content/guides/developer/advanced/maximize-reach.mdx b/docs/content/guides/developer/advanced/maximize-reach.mdx deleted file mode 100644 index c163b697cb9..00000000000 --- a/docs/content/guides/developer/advanced/maximize-reach.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Maximize your Reach -draft: true ---- - -Content coming soon \ No newline at end of file diff --git a/docs/content/guides/developer/advanced/min-gas-fees.mdx b/docs/content/guides/developer/advanced/min-gas-fees.mdx deleted file mode 100644 index f578a54cec8..00000000000 --- a/docs/content/guides/developer/advanced/min-gas-fees.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Minimize Gas Fees -draft: true ---- - -Content coming soon \ No newline at end of file diff --git a/docs/content/guides/developer/advanced/security-best-practices.mdx b/docs/content/guides/developer/advanced/security-best-practices.mdx deleted file mode 100644 index 1602d4f1276..00000000000 --- a/docs/content/guides/developer/advanced/security-best-practices.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Security Best Practices -draft: true ---- - -Content coming soon \ No newline at end of file diff --git a/docs/content/guides/developer/advanced/wallet-integrations.mdx b/docs/content/guides/developer/advanced/wallet-integrations.mdx deleted file mode 100644 index 701162934c0..00000000000 --- a/docs/content/guides/developer/advanced/wallet-integrations.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Wallet Integrations -draft: true ---- - -Content coming soon \ No newline at end of file diff --git a/docs/content/guides/developer/app-examples.mdx b/docs/content/guides/developer/app-examples.mdx deleted file mode 100644 index 0e311e5c3a0..00000000000 --- a/docs/content/guides/developer/app-examples.mdx +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: App Examples -description: Ever-growing list of example packages that demonstrate solutions built on the IOTA blockchain, written by IOTA and Move experts. Use these examples to learn IOTA and Move, and to extract techniques you can apply to your own IOTA projects. ---- - -import WarnMlRpcs from "../../_snippets/warn-ml-rpcs.mdx"; - -The ever-growing number of examples in this section showcase packages for the IOTA blockchain. Extract techniques used in these examples to apply to your own IOTA projects as they are written by IOTA and Move experts. - - - -## Examples - -IOTA is dedicated to providing a wide range of examples to guide you in proper programming techniques for the IOTA blockchain. This list will continue to grow, so check back often. - -- [Blackjack](./app-examples/blackjack.mdx): This example demonstrates the logic behind an on-chain version of the popular casino card game, Blackjack. -- [Coin Flip](./app-examples/coin-flip.mdx): The Coin Flip app demonstrates on-chain randomness. -- [Distributed Counter](./app-examples/e2e-counter.mdx): An end-to-end example that creates a basic decentralized counter that anyone can increment, but only the object owner can reset it. The example includes Move code to create the package and leverages the IOTA TypeScript SDK to provide a basic frontend. -- [Plinko](./app-examples/plinko.mdx): This example puts the classic Plinko game on chain, demonstrating use of cryptography-based strategies to create a fair and transparent game of chance. -- [Tic-tac-toe](./app-examples/tic-tac-toe.mdx): Three implementations of the classic tic-tac-toe game on the IOTA network to demonstrate different approaches to user interaction. -- [Trustless Token Swap](./app-examples/trustless-token-swap.mdx): This example demonstrates trustless token swaps on the IOTA blockchain using a shared object as an escrow account. -- [Weather Oracle](./app-examples/weather-oracle.mdx): The IOTA Weather Oracle demonstrates how to create a basic weather oracle that provides real-time weather data. diff --git a/docs/content/guides/developer/app-examples/auction.mdx b/docs/content/guides/developer/app-examples/auction.mdx deleted file mode 100644 index 5a99d3b4ddd..00000000000 --- a/docs/content/guides/developer/app-examples/auction.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Auction -draft: true ---- - -Content coming soon \ No newline at end of file diff --git a/docs/content/guides/developer/app-examples/meta-pricing-oracle.mdx b/docs/content/guides/developer/app-examples/meta-pricing-oracle.mdx deleted file mode 100644 index c899f3934e4..00000000000 --- a/docs/content/guides/developer/app-examples/meta-pricing-oracle.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Meta and Pricing Oracle -draft: true ---- - -Content coming soon \ No newline at end of file diff --git a/docs/content/guides/developer/app-examples/oracle.mdx b/docs/content/guides/developer/app-examples/oracle.mdx deleted file mode 100644 index 686dfaa6d90..00000000000 --- a/docs/content/guides/developer/app-examples/oracle.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Oracles -draft: true ---- - -Content coming soon \ No newline at end of file diff --git a/docs/content/guides/developer/app-examples/trusted-swap.mdx b/docs/content/guides/developer/app-examples/trusted-swap.mdx deleted file mode 100644 index f5bc8beb97b..00000000000 --- a/docs/content/guides/developer/app-examples/trusted-swap.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Trusted Swap -draft: true ---- - -Content coming soon \ No newline at end of file diff --git a/docs/content/guides/developer/app-examples/trustless-token-swap.mdx b/docs/content/guides/developer/app-examples/trustless-token-swap.mdx deleted file mode 100644 index cad56a5b8f7..00000000000 --- a/docs/content/guides/developer/app-examples/trustless-token-swap.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Trustless Token Swap -hide_table_of_contents: true ---- - -import AppExamplesSwapSource from "../../../_snippets/app-examples-swap-source.mdx"; - -This guide and example demonstrate an atomic swap on IOTA, which is similar to an escrow but does not require a trusted third party. Instead, this example uses a [shared object](../../../concepts/object-ownership/shared.mdx) to act as the escrow between two IOTA users wanting to trade. Shared objects are a unique concept to IOTA. Any transaction and any signer can modify it, given the changes meet the requirements set forth by the package that defined the type. - -:::info - -See [Shared versus Owned Objects](../iota-101/shared-owned.mdx) for more information on the differences between object types. - -::: - -The guide is split into three parts: - -1. [Backend](./trustless-token-swap/backend.mdx): The modules that hold the state and perform the swaps. -1. [Indexing and API Service](./trustless-token-swap/indexer-api.mdx): A service that indexes chain state to discover trades, and an API service to read this data. -1. [Frontend](./trustless-token-swap/frontend.mdx): Enables users to list objects for sale and to accept trades. - - - -## Prerequisites - -Before getting started, make sure you have: - -- [Installed the latest version of IOTA](../getting-started/iota-install.mdx). -- [Configured a valid network environment](../../../references/cli/client.mdx#set-current-environment), as you will be deploying the module on Testnet. diff --git a/docs/content/guides/developer/app-examples/turnip-town.mdx b/docs/content/guides/developer/app-examples/turnip-town.mdx deleted file mode 100644 index c48f6fb707d..00000000000 --- a/docs/content/guides/developer/app-examples/turnip-town.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Turnip Town -draft: true ---- - -Content coming soon \ No newline at end of file diff --git a/docs/content/guides/developer/getting-started.mdx b/docs/content/guides/developer/getting-started.mdx deleted file mode 100644 index ff2e4d0c9df..00000000000 --- a/docs/content/guides/developer/getting-started.mdx +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: Getting Started ---- - -IOTA is the first internet-scale programmable blockchain platform. That might read like marketing speak, but as you peruse the documentation to understand the technology, you will discover that IOTA addresses many of the problems that hold blockchains back from mass adoption. - -Before you can get started developing on IOTA, you need to understand the code repository and install its binaries. Consequently, the first two topics you need are: - -- [IOTA Environment Setup](./getting-started/iota-environment.mdx) -- [Install IOTA](./getting-started/iota-install.mdx) - -## After installing IOTA - -After you have IOTA installed on your system, you can begin to connect with a network and publish smart contracts. - -- [Connect to a IOTA Network](./getting-started/connect.mdx) -- [Connect to a Local Network](./getting-started/local-network.mdx) -- [Get IOTA Address](./getting-started/get-address.mdx) -- [Get IOTA Coins](./getting-started/get-coins.mdx) - -## GraphQL queries - -Use the GraphQL service for IOTA RPC to interact with on-chain data. - -Go to [Query IOTA RPC with GraphQL](./getting-started/graphql-rpc.mdx). - -## Related links - -After installing IOTA and setting up your development environment, use the information in the following sections to continue your development journey. - -- [App Examples](./app-examples.mdx): A mix of end-to-end examples that you can draw inspiration from in your own projects. -- [IOTA 101](./iota-101.mdx): Topics that you should know when just starting out to develop on IOTA. -- [Advanced Topics](./advanced.mdx): Topics that you might not find beneficial until you start solving more complex problems. -- [Cryptography](./cryptography.mdx): Leverage cryptography functions to provide security for your smart contract actions. diff --git a/docs/content/guides/developer/starter-templates.mdx b/docs/content/guides/developer/starter-templates.mdx deleted file mode 100644 index 6d46fa06db5..00000000000 --- a/docs/content/guides/developer/starter-templates.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Starter Templates -draft: true ---- - -Content coming soon \ No newline at end of file diff --git a/docs/content/guides/developer/zklogin-onboarding.mdx b/docs/content/guides/developer/zklogin-onboarding.mdx deleted file mode 100644 index 618bebb1ee7..00000000000 --- a/docs/content/guides/developer/zklogin-onboarding.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: zkLogin Onboarding -draft: true ---- - -Content coming soon \ No newline at end of file diff --git a/docs/content/guides/operator/archives.mdx b/docs/content/operator/archives.mdx similarity index 100% rename from docs/content/guides/operator/archives.mdx rename to docs/content/operator/archives.mdx diff --git a/docs/content/guides/operator/data-management.mdx b/docs/content/operator/data-management.mdx similarity index 89% rename from docs/content/guides/operator/data-management.mdx rename to docs/content/operator/data-management.mdx index 7fee54c23d6..66f96066913 100644 --- a/docs/content/guides/operator/data-management.mdx +++ b/docs/content/operator/data-management.mdx @@ -3,13 +3,13 @@ title: Data Management description: A high-level description of data management on the IOTA network that you can use to optimize your IOTA Full node configuration. --- -Managing the data on your IOTA Full node is critical to ensuring a healthy IOTA network. This topic provides a high-level description of data management on IOTA Full nodes that you can use to optimize your Full node configuration. For more information about IOTA Full nodes, such as pruning policies and archival settings, see [Run a IOTA Full Node](./iota-full-node.mdx). +Managing the data on your IOTA Full node is critical to ensuring a healthy IOTA network. This topic provides a high-level description of data management on IOTA Full nodes that you can use to optimize your Full node configuration. For more information about IOTA Full nodes, such as pruning policies and archival settings, see [Run a IOTA Full Node](iota-full-node.mdx). ## Basic IOTA Full node functionality The minimal version of a IOTA Full node executes all of the transactions IOTA validators commit. IOTA Full nodes also orchestrate the submitting of new transactions to the system: -![Basic IOTA Full node functionality](./images/fn-basic-functionality.png "A diagram that shows the operations of a basic IOTA Full node.") +![Basic IOTA Full node functionality](images/fn-basic-functionality.png "A diagram that shows the operations of a basic IOTA Full node.") The preceding image shows how data flows through a Full node: @@ -60,9 +60,9 @@ The current archival storage format doesn't include historic object versions. ::: -As a Full node operator, you can [enable archival fallback for your Full node](./iota-full-node.mdx#set-up-archival-fallback) by specifying the URL to upload archival data. Currently, Mysten Labs manages a IOTA archive and stores it in AWS S3. To ensure a healthy network, we encourage the IOTA community to set up additional archives to ensure archival data availability across the network. In a typical configuration, an archive trails behind the latest checkpoint by approximately 10 minutes. +As a Full node operator, you can [enable archival fallback for your Full node](iota-full-node.mdx#set-up-archival-fallback) by specifying the URL to upload archival data. Currently, Mysten Labs manages a IOTA archive and stores it in AWS S3. To ensure a healthy network, we encourage the IOTA community to set up additional archives to ensure archival data availability across the network. In a typical configuration, an archive trails behind the latest checkpoint by approximately 10 minutes. -A Full Node that starts from scratch can replay (and thus re-verify) transactions that occurred since IOTA genesis from the given archive via [configuring Archival Fallback](./iota-full-node.mdx#archival-fallback) in the `fullnode.yaml` configuration file to point to the S3 bucket that stores the archive. +A Full Node that starts from scratch can replay (and thus re-verify) transactions that occurred since IOTA genesis from the given archive via [configuring Archival Fallback](iota-full-node.mdx#archival-fallback) in the `fullnode.yaml` configuration file to point to the S3 bucket that stores the archive. A IOTA Full node that fails to retrieve checkpoints from its peers via state sync protocol falls back to downloading the missing checkpoints from its pre-configured archive. This fallback enables a Full node to catch up with the rest of the system regardless of the pruning policies of its peers. @@ -72,7 +72,7 @@ As described previously, sustainable disk usage requires IOTA Full nodes to prun Both transaction and object pruners run in the background. The logical deletion of entries from RocksDB ultimately triggers the physical compaction of data on disk, which is governed by RocksDB background jobs: the pruning effect on disk usage is not immediate and might take multiple days. -To learn more about object pruning policies, see [Object pruning](./iota-full-node.mdx#object-pruning). You can configure the pruner in two modes: +To learn more about object pruning policies, see [Object pruning](iota-full-node.mdx#object-pruning). You can configure the pruner in two modes: * **aggressive pruning** (`num-epochs-to-retain: 0`): Preferred option. IOTA prunes old object versions as soon as possible. * **epoch-based pruning** (`num-epochs-to-retain: X`): IOTA prunes old object versions after X epochs. @@ -82,11 +82,11 @@ Testing indicates that aggressive pruning results in more efficient Full Node op ::: -To learn more about transaction pruning policies, see [Transaction pruning](./iota-full-node.mdx#transaction-pruning). To configure transaction pruning, specify the `num-epochs-to-retain-for-checkpoints: X` config option. The checkpoints, including their transactions, effects and events are pruned up to X epochs ago. We suggest setting transaction pruning to 2 epochs. +To learn more about transaction pruning policies, see [Transaction pruning](iota-full-node.mdx#transaction-pruning). To configure transaction pruning, specify the `num-epochs-to-retain-for-checkpoints: X` config option. The checkpoints, including their transactions, effects and events are pruned up to X epochs ago. We suggest setting transaction pruning to 2 epochs. ### Set an archiving watermark -In case your Full node is configured to upload committed information to an archive, you should ensure that pruning doesn't occur until after the corresponding data is uploaded. To do so, set the `use-for-pruning-watermark: true` in the Fullnode.yaml file as described in [Archival fallback](./iota-full-node.mdx#archival-fallback). +In case your Full node is configured to upload committed information to an archive, you should ensure that pruning doesn't occur until after the corresponding data is uploaded. To do so, set the `use-for-pruning-watermark: true` in the Fullnode.yaml file as described in [Archival fallback](iota-full-node.mdx#archival-fallback). ## IOTA Full node key-value store backup diff --git a/docs/content/guides/operator/genesis.mdx b/docs/content/operator/genesis.mdx similarity index 88% rename from docs/content/guides/operator/genesis.mdx rename to docs/content/operator/genesis.mdx index 2cd7c109da7..0ec9de5dc85 100644 --- a/docs/content/guides/operator/genesis.mdx +++ b/docs/content/operator/genesis.mdx @@ -8,4 +8,4 @@ Genesis is the initial state of the IOTA blockchain. To launch a network, the in The genesis.blob files for each network are in the [iota-genesis](https://github.com/iotaledger/iota-genesis) repository. -See [IOTA Full Node](./iota-full-node.mdx#set-up-from-source) for how to get the genesis.blob file for each network. +See [IOTA Full Node](iota-full-node.mdx#set-up-from-source) for how to get the genesis.blob file for each network. diff --git a/docs/content/guides/operator/images/fn-basic-functionality.png b/docs/content/operator/images/fn-basic-functionality.png similarity index 100% rename from docs/content/guides/operator/images/fn-basic-functionality.png rename to docs/content/operator/images/fn-basic-functionality.png diff --git a/docs/content/guides/operator/images/mysten-cloud-snapshots.png b/docs/content/operator/images/mysten-cloud-snapshots.png similarity index 100% rename from docs/content/guides/operator/images/mysten-cloud-snapshots.png rename to docs/content/operator/images/mysten-cloud-snapshots.png diff --git a/docs/content/guides/operator/iota-full-node.mdx b/docs/content/operator/iota-full-node.mdx similarity index 99% rename from docs/content/guides/operator/iota-full-node.mdx rename to docs/content/operator/iota-full-node.mdx index 341f23e64ad..f17f44f745a 100644 --- a/docs/content/guides/operator/iota-full-node.mdx +++ b/docs/content/operator/iota-full-node.mdx @@ -333,6 +333,6 @@ authority-store-pruning-config: :::info -If you prune transactions, Archival nodes can help ensure lagging peer nodes don't lose any information. For more information, see [IOTA Archives](./archives.mdx). +If you prune transactions, Archival nodes can help ensure lagging peer nodes don't lose any information. For more information, see [IOTA Archives](archives.mdx). ::: diff --git a/docs/content/guides/operator/node-tools.mdx b/docs/content/operator/node-tools.mdx similarity index 95% rename from docs/content/guides/operator/node-tools.mdx rename to docs/content/operator/node-tools.mdx index b0f080fff14..bc58a829bd3 100644 --- a/docs/content/guides/operator/node-tools.mdx +++ b/docs/content/operator/node-tools.mdx @@ -106,7 +106,7 @@ $ iota validator update-metadata --help #### Operation cap -Operation Cap allows a validator to authorizer another account to perform certain actions on behalf of this validator. Read about [Operation Cap here](./validator-tasks.mdx#operation-cap). +Operation Cap allows a validator to authorizer another account to perform certain actions on behalf of this validator. Read about [Operation Cap here](validator-tasks.mdx#operation-cap). The Operation Cap holder (either the valdiator itself or the delegatee) updates its Gas Price and reports validator peers with the Operation Cap. @@ -156,7 +156,7 @@ $ iota validator make-validator-info ` with `main`, `devnet`, `testnet`, or `mainnet` to get the desired version. For more information on the branches available, see [IOTA Environment Setup](/guides/developer/getting-started/iota-environment.mdx). +To get the latest version of the CLI, you can run the following command from a terminal or console. Be sure to replace `` with `main`, `devnet`, `testnet`, or `mainnet` to get the desired version. For more information on the branches available, see [IOTA Environment Setup](/developer/getting-started/iota-environment.mdx). ```shell cargo install --locked --git https://github.com/iotaledger/iota.git --branch --features gas-profiler iota diff --git a/docs/content/references/cli/client.mdx b/docs/content/references/cli/client.mdx index 176b013f259..a2e790086d4 100644 --- a/docs/content/references/cli/client.mdx +++ b/docs/content/references/cli/client.mdx @@ -289,7 +289,7 @@ In both these views, you can click the top section and drag to zoom in and out o gas cost incurred in all the functions called by the function, and **Self** showing the gas cost done by only the given function. Observing a transaction's gas consumption provides useful insight of expected gas cost usage of a smart contract. -When developing a smart contract, you can [run a local network](../../guides/developer/getting-started/local-network.mdx) and publish the package to the local network. Then create a transaction that calls +When developing a smart contract, you can [run a local network](../../developer/getting-started/local-network.mdx) and publish the package to the local network. Then create a transaction that calls your published smart contract, and finally run the profiler on the transaction to see a breakdown of the gas cost. ## Publish a Move package @@ -342,7 +342,7 @@ This example also makes use of `iota move` commands. To learn more about those c $ iota client gas No gas coins are owned by this address ``` -1. If you need coins, use `iota client faucet` (not available for Mainnet). For more information on getting gas tokens, see [Get IOTA Tokens](/guides/developer/getting-started/get-coins.mdx). +1. If you need coins, use `iota client faucet` (not available for Mainnet). For more information on getting gas tokens, see [Get IOTA Tokens](/developer/getting-started/get-coins.mdx). ```shell $ iota client faucet ``` diff --git a/docs/content/references/cli/ptb.mdx b/docs/content/references/cli/ptb.mdx index 0b6f5efd49b..92b4d4f111d 100644 --- a/docs/content/references/cli/ptb.mdx +++ b/docs/content/references/cli/ptb.mdx @@ -38,7 +38,7 @@ Options: The main philosophy behind the CLI PTB support is to enable a user to build and execute a PTB from the command line. Bash scripts can be used to construct and execute the PTB just as you would do from the command line, providing great flexibility when it comes to automating different tasks. -Besides using existing [traditional PTB](/concepts/transactions/prog-txn-blocks/) related concepts, we introduce a few new and important concepts for this command. +Besides using existing [traditional PTB](../../developer/iota-101/transactions/ptb/prog-txn-blocks.mdx) related concepts, we introduce a few new and important concepts for this command. :::warning @@ -121,7 +121,7 @@ To call a specific function from a specific package, you can use the following c ### Publish -Publishing a package is one of the most important commands you need when working with IOTA. While the CLI has a standalone `publish` command, PTBs also support publishing and upgrading packages. One main difference is that with `iota client ptb`, you must explicitly transfer the `UpgradeCap` object that is returned when creating a package, or destroy it with a call to [`make_immutable`](/concepts/iota-move-concepts/packages.mdx). Here is an example on how to publish a Move project on chain using the `iota client ptb` command. It makes a call to the `iota::tx_context::sender` to acquire the sender and assigns the result of that call to the `sender` variable, and then calls the publish command. The result of `publish` is bounded to `upgrade_cap` variable, and then this object is transferred to the sender. +Publishing a package is one of the most important commands you need when working with IOTA. While the CLI has a standalone `publish` command, PTBs also support publishing and upgrading packages. One main difference is that with `iota client ptb`, you must explicitly transfer the `UpgradeCap` object that is returned when creating a package, or destroy it with a call to [`make_immutable`](../../developer/iota-101/iota-move-concepts/packages/packages.mdx). Here is an example on how to publish a Move project on chain using the `iota client ptb` command. It makes a call to the `iota::tx_context::sender` to acquire the sender and assigns the result of that call to the `sender` variable, and then calls the publish command. The result of `publish` is bounded to `upgrade_cap` variable, and then this object is transferred to the sender. ```bash iota client ptb \ diff --git a/docs/content/references/contribute/contribute-to-iota-repos.mdx b/docs/content/references/contribute/contribute-to-iota-repos.mdx index aec078a8cd2..134e31484b6 100644 --- a/docs/content/references/contribute/contribute-to-iota-repos.mdx +++ b/docs/content/references/contribute/contribute-to-iota-repos.mdx @@ -17,7 +17,7 @@ To report an issue with IOTA, [create an issue](https://github.com/iotaledger/io To contribute to IOTA source code or documentation, you need only a GitHub account. You can commit updates and then submit a PR directly from the Github website, or create a fork of the repo to your local environment and use your favorite tools to make changes. Always submit PRs to the `main` branch. -See [IOTA Environment Setup](/guides/developer/getting-started/iota-environment.mdx) for instructions on forking the IOTA repository, if necessary. +See [IOTA Environment Setup](/developer/getting-started/iota-environment.mdx) for instructions on forking the IOTA repository, if necessary. ## Contribute via the IOTA Improvement Proposal (SIP) process {#SIP} diff --git a/docs/content/references/contribute/contribution-process.mdx b/docs/content/references/contribute/contribution-process.mdx index 870d9dc7548..53cec3787b9 100644 --- a/docs/content/references/contribute/contribution-process.mdx +++ b/docs/content/references/contribute/contribution-process.mdx @@ -20,7 +20,7 @@ To create more engaging content, be sure to follow these rules in particular: ## Set up local environment {#local-environment} -Cloning the documentation locally is recommended when you are creating larger, more significant changes to the docs. See [IOTA Environment Setup](/guides/developer/getting-started/iota-environment.mdx) for instructions on forking the IOTA repository, if necessary. The documentation is in the `docs/content` directory. +Cloning the documentation locally is recommended when you are creating larger, more significant changes to the docs. See [IOTA Environment Setup](/developer/getting-started/iota-environment.mdx) for instructions on forking the IOTA repository, if necessary. The documentation is in the `docs/content` directory. 1. If you are using the recommended Visual Studio Code IDE, install [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) to ensure that your formatting is consistent. 1. After you make all your changes, stage all files with changes (`git add .` to add all modified files), create a local commit (`git commit -m “message”`), and then push all your changes to your forked repository (`git push`). diff --git a/docs/content/references/contribute/style-guide.mdx b/docs/content/references/contribute/style-guide.mdx index 4a84e5ba5a9..a4d4cdd477f 100644 --- a/docs/content/references/contribute/style-guide.mdx +++ b/docs/content/references/contribute/style-guide.mdx @@ -565,13 +565,13 @@ Use the topic title of the target topic as the link text for the link in a list -> To learn more, see [Examples of IOTA Smart Contracts](/guides/developer/app-examples.mdx). +> To learn more, see [Examples of IOTA Smart Contracts](/developer/app-examples.mdx). ```markdown -To learn more, see [Examples of IOTA Smart Contracts](/guides/developer/app-examples.mdx). +To learn more, see [Examples of IOTA Smart Contracts](/developer/app-examples.mdx). ``` @@ -583,14 +583,14 @@ Use keywords from the target topic title when using links inline. -> Before you install IOTA, make sure to install the [prerequisites](/guides/developer/getting-started/iota-install.mdx#prerequisites). +> Before you install IOTA, make sure to install the [prerequisites](/developer/getting-started/iota-install.mdx#prerequisites). ``` -Before you install IOTA, make sure to install the [prerequisites](/guides/developer/getting-started/iota-install.mdx#prerequisites). +Before you install IOTA, make sure to install the [prerequisites](/developer/getting-started/iota-install.mdx#prerequisites). ``` diff --git a/docs/content/references/iota-api.mdx b/docs/content/references/iota-api.mdx index ddc2d43433e..b823512c77a 100644 --- a/docs/content/references/iota-api.mdx +++ b/docs/content/references/iota-api.mdx @@ -4,7 +4,7 @@ title: IOTA RPC :::info -The IOTA RPC is upgrading from JSON-RPC to GraphQL. See [GraphQL for IOTA RPC](../concepts/graphql-rpc.mdx) for more information. +The IOTA RPC is upgrading from JSON-RPC to GraphQL. See [GraphQL for IOTA RPC](../developer/graphql-rpc.mdx) for more information. ::: diff --git a/docs/content/references/iota-graphql.mdx b/docs/content/references/iota-graphql.mdx index 1f581325178..1e1ca11bf4c 100644 --- a/docs/content/references/iota-graphql.mdx +++ b/docs/content/references/iota-graphql.mdx @@ -5,7 +5,7 @@ description: GraphQL is a public service for the IOTA RPC that enables you to ef GraphQL for the IOTA RPC is a public service that enables interacting with the IOTA [network](https://iota.io/networkinfo). -To get started with GraphQL for the IOTA RPC, check out the [Getting Started](../guides/developer/getting-started/graphql-rpc.mdx) guide. If you'd like to learn more about the concepts used in the GraphQL service, check out the [GraphQL](../concepts/graphql-rpc.mdx) for IOTA RPC concepts page. +To get started with GraphQL for the IOTA RPC, check out the [Getting Started](../developer/getting-started/graphql-rpc.mdx) guide. If you'd like to learn more about the concepts used in the GraphQL service, check out the [GraphQL](../developer/graphql-rpc.mdx) for IOTA RPC concepts page. ## Key Types @@ -19,6 +19,6 @@ All GraphQL API elements are accessible via the left sidebar, the following are ## Related links -- [GraphQL migration](../guides/developer/advanced/graphql-migration.mdx): Migrating to GraphQL guides you through migrating IOTA RPC projects from JSON-RPC to GraphQL. -- [GraphQL quick-start](../guides/developer/getting-started/graphql-rpc.mdx): Querying IOTA RPC with GraphQL gets you started using GraphQL to query the IOTA RPC for on-chain data. -- [GraphQL concepts](../concepts/graphql-rpc.mdx): GraphQL for IOTA RPC examines the elements of GraphQL that you should know to get the most from the service. +- [GraphQL migration](../developer/advanced/graphql-migration.mdx): Migrating to GraphQL guides you through migrating IOTA RPC projects from JSON-RPC to GraphQL. +- [GraphQL quick-start](../developer/getting-started/graphql-rpc.mdx): Querying IOTA RPC with GraphQL gets you started using GraphQL to query the IOTA RPC for on-chain data. +- [GraphQL concepts](../developer/graphql-rpc.mdx): GraphQL for IOTA RPC examines the elements of GraphQL that you should know to get the most from the service. diff --git a/docs/content/references/move/language.mdx b/docs/content/references/move/language.mdx deleted file mode 100644 index 5bcca0268bd..00000000000 --- a/docs/content/references/move/language.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Placeholder -draft: true ---- - -Content coming soon \ No newline at end of file diff --git a/docs/content/references.mdx b/docs/content/references/references.mdx similarity index 100% rename from docs/content/references.mdx rename to docs/content/references/references.mdx diff --git a/docs/content/sidebars/about-iota.js b/docs/content/sidebars/about-iota.js new file mode 100644 index 00000000000..9c4c1c6faf6 --- /dev/null +++ b/docs/content/sidebars/about-iota.js @@ -0,0 +1,47 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +const aboutIota = [ + 'about-iota/about-iota', + 'about-iota/components', + { + type: 'category', + label: 'IOTA Architecture', + collapsed: false, + link: { + type: 'doc', + id: 'about-iota/iota-architecture', + }, + items: [ + 'about-iota/iota-architecture/iota-security', + 'about-iota/iota-architecture/transaction-lifecycle', + 'about-iota/iota-architecture/consensus', + 'about-iota/iota-architecture/indexer-functions', + 'about-iota/iota-architecture/epochs', + 'about-iota/iota-architecture/protocol-upgrades', + 'about-iota/iota-architecture/staking-rewards', + ], + }, + { + type: 'category', + label: 'Tokenomics', + collapsed: false, + link: { + type: 'doc', + id: 'about-iota/tokenomics', + }, + items: [ + 'about-iota/tokenomics/proof-of-stake', + 'about-iota/tokenomics/validators-staking', + 'about-iota/tokenomics/staking-unstaking', + 'about-iota/tokenomics/iota-coin', + 'about-iota/tokenomics/iota-bridging', + 'about-iota/tokenomics/storage-fund', + 'about-iota/tokenomics/gas-pricing', + 'about-iota/tokenomics/gas-in-iota', + ], + }, + 'about-iota/research-papers', +]; +module.exports = aboutIota; diff --git a/docs/content/sidebars/concepts.js b/docs/content/sidebars/concepts.js deleted file mode 100644 index ce84b66695a..00000000000 --- a/docs/content/sidebars/concepts.js +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright (c) Mysten Labs, Inc. -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -const concepts = [ - 'concepts', - 'concepts/components', - { - type: 'category', - label: 'App Developers', - link: { - type: 'doc', - id: 'concepts/app-devs', - }, - items: [ - 'concepts/graphql-rpc', - { - type: 'category', - label: 'Object Model', - link: { - type: 'doc', - id: 'concepts/object-model', - }, - items: [ - { - type: 'category', - label: 'Object Ownership', - link: { - type: 'doc', - id: 'concepts/object-ownership', - }, - items: [ - 'concepts/object-ownership/address-owned', - 'concepts/object-ownership/immutable', - 'concepts/object-ownership/shared', - 'concepts/object-ownership/wrapped', - ], - }, - { - type: 'category', - label: 'Dynamic Fields', - link: { - type: 'doc', - id: 'concepts/dynamic-fields', - }, - items: ['concepts/dynamic-fields/tables-bags'], - }, - { - type: 'category', - label: 'Transfers', - link: { - type: 'doc', - id: 'concepts/transfers', - }, - items: ['concepts/transfers/custom-rules', 'concepts/transfers/transfer-to-object'], - }, - 'concepts/events', - 'concepts/versioning', - ], - }, - { - type: 'category', - label: 'Move Overview', - link: { - type: 'doc', - id: 'concepts/iota-move-concepts', - }, - items: [ - 'concepts/iota-move-concepts/strings', - 'concepts/iota-move-concepts/collections', - 'concepts/iota-move-concepts/init', - 'concepts/iota-move-concepts/entry-functions', - 'concepts/iota-move-concepts/one-time-witness', - { - type: 'category', - label: 'Package Upgrades', - link: { - type: 'doc', - id: 'concepts/iota-move-concepts/packages', - }, - items: [ - 'concepts/iota-move-concepts/packages/upgrade', - 'concepts/iota-move-concepts/packages/custom-policies', - ], - }, - { - type: 'category', - label: 'Patterns', - link: { - type: 'doc', - id: 'concepts/iota-move-concepts/patterns', - }, - items: [ - 'concepts/iota-move-concepts/patterns/capabilities', - 'concepts/iota-move-concepts/patterns/witness', - 'concepts/iota-move-concepts/patterns/transferrable-witness', - 'concepts/iota-move-concepts/patterns/hot-potato', - 'concepts/iota-move-concepts/patterns/id-pointer', - 'concepts/iota-move-concepts/patterns/app-extensions', - ], - }, - 'concepts/iota-move-concepts/conventions', - ], - }, - { - type: 'category', - label: 'Transactions', - link: { - type: 'doc', - id: 'concepts/transactions', - }, - items: [ - 'concepts/transactions/prog-txn-blocks', - 'concepts/transactions/sponsored-transactions', - 'concepts/transactions/gas-smashing', - ], - }, - ], - }, - { - type: 'category', - label: 'Cryptography', - link: { - type: 'doc', - id: 'concepts/cryptography', - }, - items: [ - { - type: 'category', - label: 'Transaction Authentication', - link: { - type: 'doc', - id: 'concepts/cryptography/transaction-auth', - }, - items: [ - 'concepts/cryptography/transaction-auth/keys-addresses', - 'concepts/cryptography/transaction-auth/signatures', - 'concepts/cryptography/transaction-auth/multisig', - 'concepts/cryptography/transaction-auth/offline-signing', - 'concepts/cryptography/transaction-auth/intent-signing', - ], - }, - { - type: 'category', - label: 'zkLogin', - link: { - type: 'doc', - id: 'concepts/cryptography/zklogin', - }, - items: ['concepts/cryptography/zklogin/zklogin-example'], - }, - 'concepts/cryptography/system/checkpoint-verification', - /*{ - type: 'category', - label: 'System', - link: { - type: 'doc', - id: 'concepts/cryptography/system', - }, - items: [ - 'concepts/cryptography/system/validator-signatures', - 'concepts/cryptography/system/intents-for-validation', - 'concepts/cryptography/system/checkpoint-verification', - ], - },*/ - ], - }, - { - type: 'category', - label: 'IOTA Architecture', - link: { - type: 'doc', - id: 'concepts/iota-architecture', - }, - items: [ - 'concepts/iota-architecture/high-level', - 'concepts/iota-architecture/iota-security', - 'concepts/iota-architecture/transaction-lifecycle', - 'concepts/iota-architecture/consensus', - 'concepts/iota-architecture/indexer-functions', - 'concepts/iota-architecture/epochs', - 'concepts/iota-architecture/protocol-upgrades', - 'concepts/iota-architecture/data-management-things', - 'concepts/iota-architecture/staking-rewards', - ], - }, - { - type: 'category', - label: 'Tokenomics', - link: { - type: 'doc', - id: 'concepts/tokenomics', - }, - items: [ - 'concepts/tokenomics/proof-of-stake', - 'concepts/tokenomics/validators-staking', - 'concepts/tokenomics/staking-unstaking', - 'concepts/tokenomics/iota-coin', - 'concepts/tokenomics/iota-bridging', - 'concepts/tokenomics/storage-fund', - 'concepts/tokenomics/gas-pricing', - 'concepts/tokenomics/gas-in-iota', - ], - }, - 'concepts/research-papers', -]; -module.exports = concepts; diff --git a/docs/content/sidebars/developer.js b/docs/content/sidebars/developer.js new file mode 100644 index 00000000000..22123c2d3f5 --- /dev/null +++ b/docs/content/sidebars/developer.js @@ -0,0 +1,358 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +const developer = [ + 'developer/developer', + { + type: 'category', + label: 'Getting Started', + collapsed: false, + link: { + type: 'doc', + id: 'developer/getting-started', + }, + items: [ + 'developer/getting-started/iota-environment', + 'developer/getting-started/iota-install', + 'developer/getting-started/connect', + 'developer/getting-started/local-network', + 'developer/getting-started/get-address', + 'developer/getting-started/get-coins', + 'developer/getting-started/graphql-rpc', + { + type: 'category', + label: 'Your First IOTA dApp', + collapsed: false, + link: { + type: 'doc', + id: 'developer/getting-started/first-app/first-app', + }, + items: [ + 'developer/getting-started/first-app/write-package', + 'developer/getting-started/first-app/build-test', + 'developer/getting-started/first-app/publish', + 'developer/getting-started/first-app/debug', + 'developer/getting-started/first-app/client-tssdk', + ], + }, + ], + }, + { + type: 'category', + label: 'From Solidity/EVM to Move', + collapsed: true, + link: { + type: 'doc', + id: 'developer/evm-to-move', + }, + items: [ + 'developer/evm-to-move/why-move', + 'developer/evm-to-move/tooling-apis', + 'developer/evm-to-move/creating-token', + 'developer/evm-to-move/creating-nft', + ], + }, + { + type: 'category', + label: 'IOTA 101', + link: { + type: 'doc', + id: 'developer/iota-101', + }, + items: [ + { + type: 'category', + label: 'Move Overview',link: { + type: 'doc', + id: 'developer/iota-101/iota-move-concepts/iota-move-concepts', + }, + items: [ + 'developer/iota-101/iota-move-concepts/strings', + 'developer/iota-101/iota-move-concepts/collections', + 'developer/iota-101/iota-move-concepts/init', + 'developer/iota-101/iota-move-concepts/entry-functions', + 'developer/iota-101/iota-move-concepts/one-time-witness', + { + type: 'category', + label: 'Package Upgrades', + link: { + type: 'doc', + id: 'developer/iota-101/iota-move-concepts/packages/packages', + }, + items: [ + 'developer/iota-101/iota-move-concepts/packages/upgrade', + 'developer/iota-101/iota-move-concepts/packages/custom-policies', + ], + }, + { + type: 'category', + label: 'Patterns', + link: { + type: 'doc', + id: 'developer/iota-101/iota-move-concepts/patterns', + }, + items: [ + 'developer/iota-101/iota-move-concepts/patterns/capabilities', + 'developer/iota-101/iota-move-concepts/patterns/witness', + 'developer/iota-101/iota-move-concepts/patterns/transferrable-witness', + 'developer/iota-101/iota-move-concepts/patterns/hot-potato', + 'developer/iota-101/iota-move-concepts/patterns/id-pointer', + ], + }, + 'developer/iota-101/iota-move-concepts/conventions', + ], + }, + 'developer/graphql-rpc', + { + type: 'category', + label: 'Object Model', + items:[ + 'developer/iota-101/objects/object-model', + 'developer/iota-101/objects/shared-owned', + { + type: 'category', + label: 'Object Ownership', + link: { + type: 'doc', + id: 'developer/iota-101/objects/object-ownership/object-ownership', + }, + items: [ + 'developer/iota-101/objects/object-ownership/address-owned', + 'developer/iota-101/objects/object-ownership/immutable', + 'developer/iota-101/objects/object-ownership/shared', + 'developer/iota-101/objects/object-ownership/wrapped', + ], + }, + { + type: 'category', + label: 'Dynamic Fields', + link: { + type: 'doc', + id: 'developer/iota-101/objects/dynamic-fields/dynamic-fields', + }, + items: ['developer/iota-101/objects/dynamic-fields/tables-bags'], + }, + { + type: 'category', + label: 'Transfers', + link: { + type: 'doc', + id: 'developer/iota-101/objects/transfers/transfers', + }, + items: ['developer/iota-101/objects/transfers/custom-rules', + 'developer/iota-101/objects/transfers/transfer-to-object'], + }, + 'developer/iota-101/objects/events', + 'developer/iota-101/objects/versioning', + ] + }, + { + type: 'category', + label: 'Transactions', + link: { + type: 'doc', + id: 'developer/iota-101/transactions/transactions', + }, + items:[ + 'developer/iota-101/transactions/sign-and-send-txn', + { + type:'category', + label: 'Sponsored Transactions', + link: { + type: 'doc', + id: 'developer/iota-101/transactions/sponsor-txn', + }, + items:['developer/iota-101/transactions/sponsored-transactions'] + }, + 'developer/iota-101/transactions/gas-smashing', + { + type: 'category', + label: 'Working with PTBs', + items: [ + 'developer/iota-101/transactions/ptb/prog-txn-blocks', + 'developer/iota-101/transactions/ptb/building-ptb', + 'developer/iota-101/transactions/ptb/coin-mgt', + 'developer/iota-101/transactions/ptb/simulating-refs', + ], + }, + ] + }, + { + type: 'category', + label: 'Create Coins and Tokens', + link: { + type: 'doc', + id: 'developer/iota-101/create-coin/create-coin', + }, + items: [ + 'developer/iota-101/create-coin/regulated', + 'developer/iota-101/create-coin/in-game-token', + 'developer/iota-101/create-coin/loyalty', + ], + }, + 'developer/iota-101/create-nft', + 'developer/iota-101/using-events', + 'developer/iota-101/access-time', + ], + }, + { + type: 'category', + label: 'Cryptography', + link: { + type: 'doc', + id:'developer/cryptography/explanations/cryptography', + }, + items: [ + { + type: 'category', + label: 'Explanations', + items: [ + 'developer/cryptography/explanations/cryptography', + { + type: 'category', + label: 'Transaction Authentication', + link: { + type: 'doc', + id: 'developer/cryptography/explanations/transaction-auth', + }, + items: [ + 'developer/cryptography/explanations/transaction-auth/keys-addresses', + 'developer/cryptography/explanations/transaction-auth/signatures', + 'developer/cryptography/explanations/transaction-auth/multisig', + 'developer/cryptography/explanations/transaction-auth/offline-signing', + 'developer/cryptography/explanations/transaction-auth/intent-signing', + ], + }, + { + type: 'category', + label: 'zkLogin', + link: { + type: 'doc', + id: 'developer/cryptography/explanations/zklogin', + }, + items: ['developer/cryptography/explanations/zklogin/zklogin-example'], + }, + 'developer/cryptography/explanations/system/checkpoint-verification', + ], + }, + { + type: 'category', + label: 'How To', + items: [ + 'developer/cryptography/how-to/cryptography', + 'developer/cryptography/how-to/signing', + 'developer/cryptography/how-to/groth16', + 'developer/cryptography/how-to/hashing', + 'developer/cryptography/how-to/ecvrf',] + } + ], + }, + { + type: 'category', + label: 'Advanced Topics', + link: { + type: 'doc', + id: 'developer/advanced', + }, + items: [ + /*{ + type: 'category', + label: 'Efficient Smart Contracts', + link: { + type: 'doc', + id: 'developer/advanced/efficient-smart-contracts', + }, + items: ['developer/advanced/min-gas-fees'], + },*/ + 'developer/advanced/graphql-migration', + 'developer/advanced/move-2024-migration', + 'developer/advanced/asset-tokenization', + 'developer/advanced/custom-indexer', + 'developer/advanced/stardust-on-move', + ], + }, + { + type: 'category', + label: 'App Examples', + link: { + type: 'doc', + id: 'developer/app-examples', + }, + items: [ + 'developer/app-examples/blackjack', + 'developer/app-examples/coin-flip', + 'developer/app-examples/e2e-counter', + 'developer/app-examples/plinko', + 'developer/app-examples/recaptcha', + 'developer/app-examples/tic-tac-toe', + { + type: 'category', + label: 'Trustless Token Swap', + link: { + type: 'doc', + id: 'developer/app-examples/trustless-token-swap', + }, + items: [ + 'developer/app-examples/trustless-token-swap/backend', + 'developer/app-examples/trustless-token-swap/indexer-api', + 'developer/app-examples/trustless-token-swap/frontend', + ], + }, + ], + }, + { + type:'category', + label: 'Standards', + items: [ + 'developer/standards/standards', + 'developer/standards/coin', + { + type: 'category', + label: 'Closed-Loop Token', + link: { + type: 'doc', + id: 'developer/standards/closed-loop-token', + }, + items: [ + 'developer/standards/closed-loop-token/action-request', + 'developer/standards/closed-loop-token/token-policy', + 'developer/standards/closed-loop-token/spending', + 'developer/standards/closed-loop-token/rules', + 'developer/standards/closed-loop-token/coin-token-comparison', + ], + }, + 'developer/standards/kiosk', + 'developer/standards/kiosk-apps', + { + type: 'category', + label: 'DeepBook', + link: { + type: 'doc', + id: 'developer/standards/deepbook', + }, + items: [ + 'developer/standards/deepbook/design', + 'developer/standards/deepbook/orders', + 'developer/standards/deepbook/pools', + 'developer/standards/deepbook/query-the-pool', + 'developer/standards/deepbook/routing-a-swap', + 'developer/standards/deepbook/trade-and-swap', + ], + }, + 'developer/standards/display', + 'developer/standards/wallet-standard', + ] + }, + 'developer/dev-cheat-sheet', + { + type:'category', + label: 'Integrate Your Exchange', + items:[ + 'developer/exchange-integration/exchange-integration', + 'developer/exchange-integration/stardust-migration', + ] + } + ] +; +module.exports = developer; diff --git a/docs/content/sidebars/guides.js b/docs/content/sidebars/guides.js deleted file mode 100644 index e171b64fb9f..00000000000 --- a/docs/content/sidebars/guides.js +++ /dev/null @@ -1,233 +0,0 @@ -// Copyright (c) Mysten Labs, Inc. -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -const guides = [ - { - type: 'doc', - label: 'Guides', - id: 'guides', - }, - { - type: 'category', - label: 'Developer Guides', - collapsed: false, - link: { - type: 'doc', - id: 'guides/developer', - }, - items: [ - { - type: 'category', - label: 'Getting Started', - collapsed: false, - link: { - type: 'doc', - id: 'guides/developer/getting-started', - }, - items: [ - 'guides/developer/getting-started/iota-environment', - 'guides/developer/getting-started/iota-install', - 'guides/developer/getting-started/connect', - 'guides/developer/getting-started/local-network', - 'guides/developer/getting-started/get-address', - 'guides/developer/getting-started/get-coins', - 'guides/developer/getting-started/graphql-rpc', - ], - }, - { - type: 'category', - label: 'From Solidity/EVM to Move', - collapsed: true, - link: { - type: 'doc', - id: 'guides/developer/evm-to-move', - }, - items: [ - 'guides/developer/evm-to-move/why-move', - 'guides/developer/evm-to-move/tooling-apis', - 'guides/developer/evm-to-move/creating-token', - 'guides/developer/evm-to-move/creating-nft', - ], - }, - { - type: 'category', - label: 'Your First IOTA dApp', - link: { - type: 'doc', - id: 'guides/developer/first-app', - }, - items: [ - 'guides/developer/first-app/write-package', - 'guides/developer/first-app/build-test', - 'guides/developer/first-app/publish', - 'guides/developer/first-app/debug', - 'guides/developer/first-app/client-tssdk', - ], - }, - { - type: 'category', - label: 'IOTA 101', - link: { - type: 'doc', - id: 'guides/developer/iota-101', - }, - items: [ - 'guides/developer/iota-101/shared-owned', - { - type: 'category', - label: 'Create Coins and Tokens', - link: { - type: 'doc', - id: 'guides/developer/iota-101/create-coin', - }, - items: [ - 'guides/developer/iota-101/create-coin/regulated', - 'guides/developer/iota-101/create-coin/in-game-token', - 'guides/developer/iota-101/create-coin/loyalty', - ], - }, - 'guides/developer/iota-101/create-nft', - 'guides/developer/iota-101/using-events', - 'guides/developer/iota-101/access-time', - 'guides/developer/iota-101/sign-and-send-txn', - 'guides/developer/iota-101/sponsor-txn', - { - type: 'category', - label: 'Working with PTBs', - items: [ - 'guides/developer/iota-101/building-ptb', - 'guides/developer/iota-101/coin-mgt', - 'guides/developer/iota-101/simulating-refs', - ], - }, - ], - }, - { - type: 'category', - label: 'Cryptography', - link: { - type: 'doc', - id: 'guides/developer/cryptography', - }, - items: [ - 'guides/developer/cryptography/signing', - 'guides/developer/cryptography/groth16', - 'guides/developer/cryptography/hashing', - 'guides/developer/cryptography/ecvrf', - ], - }, - { - type: 'category', - label: 'Advanced Topics', - link: { - type: 'doc', - id: 'guides/developer/advanced', - }, - items: [ - /*{ - type: 'category', - label: 'Efficient Smart Contracts', - link: { - type: 'doc', - id: 'guides/developer/advanced/efficient-smart-contracts', - }, - items: ['guides/developer/advanced/min-gas-fees'], - },*/ - 'guides/developer/advanced/graphql-migration', - 'guides/developer/advanced/move-2024-migration', - 'guides/developer/advanced/asset-tokenization', - 'guides/developer/advanced/custom-indexer', - 'guides/developer/advanced/stardust-on-move', - ], - }, - { - type: 'category', - label: 'App Examples', - link: { - type: 'doc', - id: 'guides/developer/app-examples', - }, - items: [ - 'guides/developer/app-examples/auction', - 'guides/developer/app-examples/blackjack', - 'guides/developer/app-examples/coin-flip', - 'guides/developer/app-examples/e2e-counter', - { - type: 'category', - label: 'Oracles', - link: { - type: 'doc', - id: 'guides/developer/app-examples/oracle', - }, - items: [ - 'guides/developer/app-examples/weather-oracle', - 'guides/developer/app-examples/meta-pricing-oracle', - ], - }, - 'guides/developer/app-examples/plinko', - 'guides/developer/app-examples/recaptcha', - 'guides/developer/app-examples/tic-tac-toe', - { - type: 'category', - label: 'Trustless Token Swap', - link: { - type: 'doc', - id: 'guides/developer/app-examples/trustless-token-swap', - }, - items: [ - 'guides/developer/app-examples/trustless-token-swap/backend', - 'guides/developer/app-examples/trustless-token-swap/indexer-api', - 'guides/developer/app-examples/trustless-token-swap/frontend', - ], - }, - 'guides/developer/app-examples/trusted-swap', - 'guides/developer/app-examples/turnip-town', - ], - }, - 'guides/developer/starter-templates', - 'guides/developer/zklogin-onboarding', - 'guides/developer/dev-cheat-sheet', - ], - }, - { - type: 'category', - label: 'Operator Guides', - link: { - type: 'doc', - id: 'guides/operator', - }, - items: [ - 'guides/operator/iota-full-node', - 'guides/operator/validator-config', - 'guides/operator/data-management', - 'guides/operator/snapshots', - 'guides/operator/archives', - 'guides/operator/genesis', - 'guides/operator/validator-committee', - 'guides/operator/validator-tasks', - 'guides/operator/node-tools', - 'guides/operator/exchange-integration', - ], - }, - { - type: 'category', - label: 'Migrating IOTA/Shimmer Stardust', - link: { - type: 'doc', - id: 'guides/stardust-migration', - }, - items: [ - 'guides/stardust/move-models', - 'guides/stardust/addresses', - 'guides/stardust/units', - 'guides/stardust/migration-process', - 'guides/stardust/claiming', - 'guides/stardust/vested', - 'guides/stardust/testing', - 'guides/stardust/if-tools', - 'guides/stardust/faq', - ], - }, -]; -module.exports = guides; diff --git a/docs/content/sidebars/operator.js b/docs/content/sidebars/operator.js new file mode 100644 index 00000000000..b66d6fd3884 --- /dev/null +++ b/docs/content/sidebars/operator.js @@ -0,0 +1,18 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +const operator = [ + 'operator/operator', + 'operator/iota-full-node', + 'operator/validator-config', + 'operator/data-management', + 'operator/snapshots', + 'operator/archives', + 'operator/genesis', + 'operator/validator-committee', + 'operator/validator-tasks', + 'operator/node-tools', + +]; +module.exports = operator; diff --git a/docs/content/sidebars/references.js b/docs/content/sidebars/references.js index 0fad7bb46e1..49f7d40216e 100644 --- a/docs/content/sidebars/references.js +++ b/docs/content/sidebars/references.js @@ -6,7 +6,7 @@ const references = [ { type: 'doc', label: 'References', - id: 'references', + id: 'references/references', }, { type: 'category', diff --git a/docs/content/sidebars/standards.js b/docs/content/sidebars/standards.js deleted file mode 100644 index dcbdc259e19..00000000000 --- a/docs/content/sidebars/standards.js +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) Mysten Labs, Inc. -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -const standards = [ - 'standards', - 'standards/coin', - { - type: 'category', - label: 'Closed-Loop Token', - link: { - type: 'doc', - id: 'standards/closed-loop-token', - }, - items: [ - 'standards/closed-loop-token/action-request', - 'standards/closed-loop-token/token-policy', - 'standards/closed-loop-token/spending', - 'standards/closed-loop-token/rules', - 'standards/closed-loop-token/coin-token-comparison', - ], - }, - 'standards/kiosk', - 'standards/kiosk-apps', - { - type: 'category', - label: 'DeepBook', - link: { - type: 'doc', - id: 'standards/deepbook', - }, - items: [ - 'standards/deepbook/design', - 'standards/deepbook/orders', - 'standards/deepbook/pools', - 'standards/deepbook/query-the-pool', - 'standards/deepbook/routing-a-swap', - 'standards/deepbook/trade-and-swap', - ], - }, - 'standards/display', - 'standards/wallet-standard', -]; -module.exports = standards; diff --git a/docs/site/docusaurus.config.js b/docs/site/docusaurus.config.js index 4b497d1a56d..3c668357e22 100644 --- a/docs/site/docusaurus.config.js +++ b/docs/site/docusaurus.config.js @@ -181,20 +181,24 @@ const config = { }, items: [ { - label: "Guides", - to: "guides", + label: "About IOTA", + to: "about-iota", }, { - label: "Concepts", - to: "concepts", + label: "Developers", + to: "developer", }, { - label: "Standards", - to: "standards", + label: "Node Operators", + to: "operator", }, { - label: "References", - to: "references", + label: "References", + to: "references", + }, + { + label: "Integrate Your Exchange", + to: "developer/exchange-integration/", }, /* diff --git a/docs/site/sidebars.js b/docs/site/sidebars.js index 8df7422d037..1fd99ac962c 100644 --- a/docs/site/sidebars.js +++ b/docs/site/sidebars.js @@ -3,16 +3,16 @@ // SPDX-License-Identifier: Apache-2.0 //const why_iota = require("../content/sidebars/why_iota.js"); -const guides = require("../content/sidebars/guides.js"); -const concepts = require("../content/sidebars/concepts.js"); -const standards = require("../content/sidebars/standards.js"); +const developer = require("../content/sidebars/developer.js"); +const aboutIota = require("../content/sidebars/about-iota.js"); +const operator = require("../content/sidebars/operator.js"); const references = require("../content/sidebars/references.js"); const sidebars = { //whyIOTASidebar: why_iota, - guidesSidebar: guides, - conceptsSidebar: concepts, - standardsSidebar: standards, + developerSidebar: developer, + operatorSidebar: operator, + aboutIotaSidebar: aboutIota, referencesSidebar: references, }; diff --git a/docs/site/src/pages/index.js b/docs/site/src/pages/index.js index 321ad0ebc7b..201a67631b4 100644 --- a/docs/site/src/pages/index.js +++ b/docs/site/src/pages/index.js @@ -38,46 +38,46 @@ export default function Home() {

IOTA Documentation

- Discover the power of IOTA through examples, guides, and concepts + Discover the power of IOTA through examples, guides, and explanations.

- + Tokenomics - + Cryptography - + Standards Getting started - + IOTA Developer Basics - + Move Validator configuration Run a IOTA Full node @@ -118,7 +118,7 @@ export default function Home() { IOTA dev cheat sheet @@ -126,7 +126,7 @@ export default function Home() { Build your dApp on IOTA {isHomePage && ( Get started diff --git a/docs/site/vercel.json b/docs/site/vercel.json deleted file mode 100644 index 8d8f91296c9..00000000000 --- a/docs/site/vercel.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "redirects": [ - { "source": "/testnet/:path*", "destination": "/:path*", "permanent": false }, - { "source": "/devnet/:path*", "destination": "/:path*", "permanent": false }, - { "source": "/learn/object-package-versions", "destination": "/concepts/dynamic-fields/versioning", "permanent": true }, - { "source": "/learn/objects", "destination": "/concepts/object-model", "permanent": true }, - { "source": "/learn/about-iota", "destination": "/concepts/components", "permanent": true }, - { "source": "/learn/index", "destination": "/concepts", "permanent": true }, - { "source": "/learn", "destination": "/concepts", "permanent": true }, - { "source": "/learn/sponsored-transactions", "destination": "/concepts/transactions/sponsored-transactions", "permanent": true }, - { "source": "/learn/why-move", "destination": "/concepts/iota-move-concepts", "permanent": true }, - { "source": "/learn/iota-move-diffs", "destination": "/concepts/iota-move-concepts", "permanent": true }, - { "source": "/learn/transactions", "destination": "/concepts/transactions", "permanent": true }, - { "source": "/learn/cryptography/groth16", "destination": "/guides/developer/cryptography/groth16", "permanent": true }, - { "source": "/learn/cryptography/iota-multisig", "destination": "/concepts/cryptography/transaction-auth/multisig", "permanent": true }, - { "source": "/learn/cryptography/iota-signatures", "destination": "/concepts/cryptography/transaction-auth/signatures", "permanent": true }, - { "source": "/learn/cryptography/hashing", "destination": "/guides/developer/cryptography/hashing", "permanent": true }, - { "source": "/learn/cryptography/iota-intent-signing", "destination": "/concepts/cryptography/transaction-auth/intent-signing", "permanent": true }, - { "source": "/learn/cryptography/index", "destination": "/concepts/cryptography", "permanent": true }, - { "source": "/learn/cryptography", "destination": "/concepts/cryptography", "permanent": true }, - { "source": "/learn/cryptography/ecvrf", "destination": "/guides/developer/cryptography/ecvrf", "permanent": true }, - { "source": "/learn/cryptography/iota-move-signatures", "destination": "/concepts/cryptography/transaction-auth/signatures", "permanent": true }, - { "source": "/learn/cryptography/iota-offline-signing", "destination": "/concepts/cryptography/transaction-auth/offline-signing", "permanent": true }, - { "source": "/learn/architecture/iota-full-node-data", "destination": "/guides/operator/data-management", "permanent": true }, - { "source": "/learn/architecture/validators", "destination": "/guides/operator/validator-committee", "permanent": true }, - { "source": "/learn/tokenomics/storage-fund", "destination": "/concepts/tokenomics/storage-fund", "permanent": true }, - { "source": "/learn/tokenomics/iota-token", "destination": "/concepts/tokenomics/iota-token", "permanent": true }, - { "source": "/learn/tokenomics/gas-pricing", "destination": "/concepts/tokenomics/gas-pricing", "permanent": true }, - { "source": "/learn/tokenomics/proof-of-stake", "destination": "/concepts/tokenomics/proof-of-stake", "permanent": true }, - { "source": "/learn/tokenomics/gas-in-iota", "destination": "/concepts/tokenomics/gas-in-iota", "permanent": true }, - { "source": "/learn/tokenomics/index", "destination": "/concepts/tokenomics", "permanent": true }, - { "source": "/learn/tokenomics", "destination": "/concepts/tokenomics", "permanent": true }, - { "source": "/explore/examples", "destination": "/guides/developer/app-examples", "permanent": true }, - { "source": "/explore/tutorials", "destination": "/guides", "permanent": true }, - { "source": "/explore/index", "destination": "/concepts", "permanent": true }, - { "source": "/explore", "destination": "/concepts", "permanent": true }, - { "source": "/explore/iota-explorer", "destination": "https://docs.mystenlabs.com/explorer", "permanent": true }, - { "source": "/build/iota-gas-charges", "destination": "/concepts/tokenomics/gas-pricing", "permanent": true }, - { "source": "/build/iota-json", "destination": "/references/iota-api", "permanent": true }, - { "source": "/build/event_api", "destination": "/guides/developer/iota-101/using-events", "permanent": true }, - { "source": "/build/dev_cheat_sheet", "destination": "/guides/developer/dev-cheat-sheet", "permanent": true }, - { "source": "/build/iota-object-display", "destination": "/standards/display", "permanent": true }, - { "source": "/build/fullnode", "destination": "/guides/operator/iota-full-node", "permanent": true }, - { "source": "/build/json-rpc", "destination": "/references/iota-api", "permanent": true }, - { "source": "/build/iota-transfer-policy", "destination": "/concepts/dynamic-fields/transfers/custom-rules", "permanent": true }, - { "source": "/build/snapshot", "destination": "/guides/operator/snapshots", "permanent": true }, - { "source": "/build/iota-kiosk", "destination": "/standards/kiosk", "permanent": true }, - { "source": "/build/faucet", "destination": "/guides/developer/getting-started/get-coins", "permanent": true }, - { "source": "/build/install", "destination": "/guides/developer/getting-started/iota-install", "permanent": true }, - { "source": "/build/iota-local-network", "destination": "/guides/developer/getting-started/local-network", "permanent": true }, - { "source": "/build/comms", "destination": "/guides/developer/getting-started/connect", "permanent": true }, - { "source": "/build/index", "destination": "/guides", "permanent": true }, - { "source": "/build", "destination": "/guides", "permanent": true }, - { "source": "/build/rust-sdk", "destination": "/references/sdk/rust-sdk", "permanent": true }, - { "source": "/build/rpc-best-practices", "destination": "/references/iota-api/rpc-best-practices", "permanent": true }, - { "source": "/build/zk_login", "destination": "/concepts/cryptography/zklogin", "permanent": true }, - { "source": "/build/package-upgrades", "destination": "/concepts/iota-move-concepts/packages/upgrade", "permanent": true }, - { "source": "/build/custom-upgrade-policy", "destination": "/concepts/iota-move-concepts/packages/custom-policies", "permanent": true }, - { "source": "/build/cli-client", "destination": "/references/cli/client", "permanent": true }, - { "source": "/build/connect-iota-network", "destination": "/guides/developer/getting-started/connect", "permanent": true }, - { "source": "/build/prog-trans-ts-sdk", "destination": "/guides/developer/iota-101/building-ptb", "permanent": true }, - { "source": "/build/validator-node", "destination": "/guides/operator/validator-config", "permanent": true }, - { "source": "/build/move/debug-publish", "destination": "/guides/developer/first-app/debug", "permanent": true }, - { "source": "/build/move/write-package", "destination": "/guides/developer/first-app/write-package", "permanent": true }, - { "source": "/build/move/lock-file", "destination": "/references/move/move-lock", "permanent": true }, - { "source": "/build/move/build-test", "destination": "/guides/developer/first-app/build-test", "permanent": true }, - { "source": "/build/move/manifest", "destination": "/references/move/move-toml", "permanent": true }, - { "source": "/build/move/index", "destination": "/guides/developer/iota-101", "permanent": true }, - { "source": "/build/move", "destination": "/guides/developer/iota-101", "permanent": true }, - { "source": "/build/move/time", "destination": "/guides/developer/iota-101/access-time", "permanent": true }, - { "source": "/build/move/iota-move-library", "destination": "/concepts/iota-move-concepts", "permanent": true }, - { "source": "/build/programming-with-objects/ch6-collections", "destination": "/concepts/dynamic-fields/tables-bags", "permanent": true }, - { "source": "/build/programming-with-objects/ch1-object-basics", "destination": "/concepts/object-model", "permanent": true }, - { "source": "/build/programming-with-objects/ch4-object-wrapping", "destination": "/concepts/object-ownership/wrapped", "permanent": true }, - { "source": "/build/programming-with-objects/ch2-using-objects", "destination": "/concepts/object-ownership", "permanent": true }, - { "source": "/build/programming-with-objects/index", "destination": "/concepts/object-model", "permanent": true }, - { "source": "/build/programming-with-objects/ch3-immutable-objects", "destination": "/concepts/object-ownership/immutable", "permanent": true }, - { "source": "/build/programming-with-objects/ch5-dynamic-fields", "destination": "/concepts/dynamic-fields", "permanent": true }, - { "source": "/reference/iota-json", "destination": "/iota-api-ref", "permanent": true }, - { "source": "/reference/index", "destination": "/references", "permanent": true }, - { "source": "/reference", "destination": "/references", "permanent": true }, - { "source": "/concepts/dynamic-fields/events", "destination": "/concepts/events", "permanent": true }, - { "source": "/concepts/dynamic-fields/versioning", "destination": "/concepts/versioning", "permanent": true }, - { "source": "/learn/exchange-integration-guide", "destination": "/guides/operator/exchange-integration", "permanent": true }, - { "source": "/learn/exchange-integration-faq", "destination": "/guides/operator/exchange-integration", "permanent": true }, - { "source": "/learn/how-iota-works", "destination": "/concepts/components", "permanent": true }, - { "source": "/learn/iota-compared", "destination": "/concepts/components", "permanent": true }, - { "source": "/learn/iota-bridging", "destination": "/concepts/tokenomics/iota-bridging", "permanent": true }, - { "source": "/concepts/transactions/transaction-lifecycle", "destination": "/concepts/iota-architecture/transaction-lifecycle", "permanent": true}, - { "source": "/standards/closed-loop-token/overview", "destination": "/standards/closed-loop-token", "permanent": true}, - { "source": "/concepts/dynamic-fields/transfers/custom-rules", "destination": "/concepts/transfers/custom-rules", "permanent": true}, - { "source": "/concepts/dynamic-fields/transfers/transfer-to-object", "destination": "/concepts/transfers/transfer-to-object", "permanent": true}, - { "source": "/references/iota-graphql/:path*", "destination": "/references/iota-api/iota-graphql/:path*", "permanent": true}, - { "source": "/references/research-papers", "destination": "/concepts/research-papers", "permanent": true}, - { "source": "/guides/developer/app-examples/trading/:path*", "destination": "/guides/developer/app-examples/trustless-token-swap/:path*", "permanent": true}, - { "source": "/concepts/graphql-rpc/:path*", "destination": "/concepts/graphql-rpc", "permanent": true} - ] - } From 1180759172c5b0f76bb27d934233bc46e41f081b Mon Sep 17 00:00:00 2001 From: Lucas Tortora Date: Mon, 8 Jul 2024 13:23:56 -0300 Subject: [PATCH 02/37] replaced navbar item with announcement merge from develop --- .../execution-architecture/adapter.mdx | 0 .../execution-architecture/iota-execution.mdx | 0 .../execution-architecture/natives.mdx | 0 .../exchange-integration.mdx | 8 +- docs/content/developer/stardust/exchanges.mdx | 14 +- .../mutations/execute-transaction-block.mdx | 28 ++- .../reference/api/queries/address.mdx | 3 +- .../reference/api/queries/available-range.mdx | 3 +- .../api/queries/chain-identifier.mdx | 4 +- .../reference/api/queries/checkpoint.mdx | 8 +- .../reference/api/queries/coins.mdx | 5 +- .../reference/api/queries/epoch.mdx | 6 +- .../reference/api/queries/object.mdx | 11 +- .../reference/api/queries/owner.mdx | 7 +- .../reference/api/queries/protocol-config.mdx | 7 +- .../api/queries/resolve-iotans-address.mdx | 3 +- .../reference/api/queries/type.mdx | 4 +- .../api/queries/verify-zklogin-signature.mdx | 19 +- ...address-transaction-block-relationship.mdx | 3 +- .../reference/types/enums/feature.mdx | 7 +- .../reference/types/enums/move-ability.mdx | 3 +- .../reference/types/enums/move-visibility.mdx | 10 +- .../reference/types/enums/object-kind.mdx | 11 +- .../reference/types/enums/stake-status.mdx | 3 +- .../types/enums/zk-login-intent-scope.mdx | 4 +- .../reference/types/inputs/checkpoint-id.mdx | 3 +- .../types/inputs/dynamic-field-name.mdx | 3 +- .../reference/types/inputs/object-filter.mdx | 23 +- .../types/inputs/transaction-block-filter.mdx | 3 +- .../types/inputs/transaction-metadata.mdx | 8 +- .../types/interfaces/imove-object.mdx | 4 +- .../reference/types/interfaces/iobject.mdx | 4 +- .../reference/types/interfaces/iowner.mdx | 9 +- .../reference/types/objects/active-jwk.mdx | 3 +- .../reference/types/objects/address-owner.mdx | 3 +- .../reference/types/objects/address.mdx | 31 ++- .../types/objects/available-range.mdx | 3 +- .../types/objects/balance-change.mdx | 6 +- .../objects/change-epoch-transaction.mdx | 26 +- .../reference/types/objects/checkpoint.mdx | 34 +-- .../reference/types/objects/coin-metadata.mdx | 97 ++++---- .../reference/types/objects/coin.mdx | 97 ++++---- .../consensus-commit-prologue-transaction.mdx | 9 +- .../types/objects/dry-run-effect.mdx | 3 +- .../types/objects/dry-run-result.mdx | 4 +- .../reference/types/objects/dynamic-field.mdx | 29 ++- .../objects/end-of-epoch-transaction.mdx | 10 +- .../reference/types/objects/epoch.mdx | 38 +-- .../reference/types/objects/event.mdx | 7 +- .../types/objects/execution-result.mdx | 9 +- .../reference/types/objects/gas-coin.mdx | 5 +- .../types/objects/gas-cost-summary.mdx | 11 +- .../reference/types/objects/gas-effects.mdx | 3 +- .../reference/types/objects/gas-input.mdx | 10 +- .../types/objects/genesis-transaction.mdx | 3 +- .../reference/types/objects/immutable.mdx | 4 +- .../reference/types/objects/input.mdx | 3 +- .../types/objects/iotans-registration.mdx | 97 ++++---- .../reference/types/objects/linkage.mdx | 6 +- .../objects/make-move-vec-transaction.mdx | 3 +- .../reference/types/objects/move-function.mdx | 17 +- .../reference/types/objects/move-module.mdx | 4 +- .../reference/types/objects/move-object.mdx | 105 ++++---- .../reference/types/objects/move-package.mdx | 93 +++---- .../reference/types/objects/move-struct.mdx | 11 +- .../reference/types/objects/move-value.mdx | 7 +- .../reference/types/objects/object.mdx | 89 ++++--- .../types/objects/open-move-type.mdx | 5 +- .../types/objects/owned-or-immutable.mdx | 4 +- .../reference/types/objects/owner.mdx | 55 ++-- .../reference/types/objects/parent.mdx | 7 +- .../programmable-transaction-block.mdx | 5 +- .../types/objects/protocol-configs.mdx | 20 +- .../types/objects/publish-transaction.mdx | 3 +- .../reference/types/objects/receiving.mdx | 4 +- .../reference/types/objects/result.mdx | 5 +- .../reference/types/objects/safe-mode.mdx | 10 +- .../types/objects/service-config.mdx | 38 +-- .../reference/types/objects/shared-input.mdx | 11 +- .../types/objects/shared-object-delete.mdx | 12 +- .../types/objects/shared-object-read.mdx | 4 +- .../reference/types/objects/shared.mdx | 5 +- .../types/objects/split-coins-transaction.mdx | 4 +- .../reference/types/objects/stake-subsidy.mdx | 19 +- .../reference/types/objects/staked-iota.mdx | 100 ++++---- .../reference/types/objects/storage-fund.mdx | 9 +- .../types/objects/system-parameters.mdx | 14 +- .../objects/transaction-block-effects.mdx | 15 +- .../types/objects/transaction-block.mdx | 39 +-- .../objects/transfer-objects-transaction.mdx | 4 +- .../types/objects/upgrade-transaction.mdx | 3 +- .../reference/types/objects/validator-set.mdx | 17 +- .../reference/types/objects/validator.mdx | 26 +- .../types/unions/dynamic-field-value.mdx | 5 +- .../unions/end-of-epoch-transaction-kind.mdx | 7 +- .../reference/types/unions/object-owner.mdx | 19 +- .../types/unions/programmable-transaction.mdx | 8 +- .../types/unions/transaction-argument.mdx | 8 +- .../types/unions/transaction-block-kind.mdx | 30 ++- .../types/unions/unchanged-shared-object.mdx | 12 +- docs/content/sidebars/about-iota.js | 9 + docs/content/sidebars/concepts.js | 216 ---------------- docs/content/sidebars/developer.js | 25 +- docs/content/sidebars/guides.js | 234 ------------------ docs/content/sidebars/standards.js | 54 ---- docs/site/docusaurus.config.js | 15 +- 106 files changed, 961 insertions(+), 1227 deletions(-) rename docs/content/{concepts => about-iota}/execution-architecture/adapter.mdx (100%) rename docs/content/{concepts => about-iota}/execution-architecture/iota-execution.mdx (100%) rename docs/content/{concepts => about-iota}/execution-architecture/natives.mdx (100%) delete mode 100644 docs/content/sidebars/concepts.js delete mode 100644 docs/content/sidebars/guides.js delete mode 100644 docs/content/sidebars/standards.js diff --git a/docs/content/concepts/execution-architecture/adapter.mdx b/docs/content/about-iota/execution-architecture/adapter.mdx similarity index 100% rename from docs/content/concepts/execution-architecture/adapter.mdx rename to docs/content/about-iota/execution-architecture/adapter.mdx diff --git a/docs/content/concepts/execution-architecture/iota-execution.mdx b/docs/content/about-iota/execution-architecture/iota-execution.mdx similarity index 100% rename from docs/content/concepts/execution-architecture/iota-execution.mdx rename to docs/content/about-iota/execution-architecture/iota-execution.mdx diff --git a/docs/content/concepts/execution-architecture/natives.mdx b/docs/content/about-iota/execution-architecture/natives.mdx similarity index 100% rename from docs/content/concepts/execution-architecture/natives.mdx rename to docs/content/about-iota/execution-architecture/natives.mdx diff --git a/docs/content/developer/exchange-integration/exchange-integration.mdx b/docs/content/developer/exchange-integration/exchange-integration.mdx index cb8969d26cb..2380c11f845 100644 --- a/docs/content/developer/exchange-integration/exchange-integration.mdx +++ b/docs/content/developer/exchange-integration/exchange-integration.mdx @@ -18,7 +18,7 @@ For best results, run IOTA Full nodes on Linux. IOTA supports the Ubuntu and Deb ## Local testing -You can develop and test your integration using a local development server. It will spin up a local network with some test nodes, an indexer, and a faucet. You can find detailed instructions in the [local development guide](../developer/getting-started/local-network.mdx). +You can develop and test your integration using a local development server. It will spin up a local network with some test nodes, an indexer, and a faucet. You can find detailed instructions in the [local development guide](../getting-started/local-network.mdx). ## Configure a IOTA Full node @@ -169,7 +169,7 @@ console.log('Balance in Nano (1_000_000_000 Nano = 1 IOTA): ', balance.totalBala :::info Event Tracking -It's also possible to use event tracking to monitor addresses for incoming transactions. For more information on how events work and how to use them see the ["Using Events"](../developer/iota-101/using-events.mdx) guide. +It's also possible to use event tracking to monitor addresses for incoming transactions. For more information on how events work and how to use them see the ["Using Events"](../iota-101/using-events.mdx) guide. ::: @@ -180,7 +180,7 @@ IOTA is a DAG-based blockchain and uses checkpoints for node synchronization and - Checkpoints do not fork, roll back, or reorganize. - IOTA creates one checkpoint about every 3 seconds. -For more information about confirming finality, see the [Verifying Finality](../../concepts/iota-architecture/transaction-lifecycle.mdx#verifying-finality) section in the IOTA Architecture documentation. +For more information about confirming finality, see the [Verifying Finality](../../about-iota/iota-architecture/transaction-lifecycle.mdx#verifying-finality) section in the IOTA Architecture documentation. ### Checkpoint API operations @@ -234,4 +234,4 @@ IOTA supports the following API operations related to transferring IOTA between ## Signing transactions -Refer to [IOTA Signatures](../../concepts/cryptography/transaction-auth/signatures.mdx) for more details on signature validity requirements. +Refer to [IOTA Signatures](../cryptography/explanations/transaction-auth/signatures.mdx) for more details on signature validity requirements. diff --git a/docs/content/developer/stardust/exchanges.mdx b/docs/content/developer/stardust/exchanges.mdx index 41fa37d202a..8e0a72587b8 100644 --- a/docs/content/developer/stardust/exchanges.mdx +++ b/docs/content/developer/stardust/exchanges.mdx @@ -1,7 +1,7 @@ --- - title: Exchange and Custody Providers Migration - sidebar_label: Exchanges & Custody Providers - description: Relevant information for exchanges and custody providers that want to migrate to the new Move based IOTA network. +title: Exchange and Custody Providers Migration +sidebar_label: Exchanges & Custody Providers +description: Relevant information for exchanges and custody providers that want to migrate to the new Move based IOTA network. --- In 2024, the IOTA Foundation made the strategic decision to replace the existing Stardust protocol with a completely new technology stack based on the Move programming model. This fast-tracks IOTA to have programmability on the base layer (not just Layer-2 chains) without needing several additional breaking releases in between working towards that milestone. This is the biggest change ever happening to the IOTA technology stack, which has implications for integrators like exchanges and custody providers: @@ -26,7 +26,7 @@ Once the new network goes live, the old network will be shut down immediately. I ::: -With the new network, we are moving away from the UTXO model (which offers limited functionality) towards a fully programmable [object-based](../../concepts/object-model.mdx) representation of assets. No assets will be lost, and functionality will be inherited, but interaction with those assets will be different from how it used to work. +With the new network, we are moving away from the UTXO model (which offers limited functionality) towards a fully programmable [object-based](../iota-101/objects/object-model.mdx) representation of assets. No assets will be lost, and functionality will be inherited, but interaction with those assets will be different from how it used to work. ### Basic Token Transfers @@ -34,11 +34,11 @@ The most common use case for exchanges and custody providers regarding integrati #### `Coin` objects -`Coin` objects are the de-facto way to represent fungible assets on the IOTA Network. Certain assumptions apply to `Coin` objects as per the [Coin Standard](../../standards/coin.mdx): +`Coin` objects are the de-facto way to represent fungible assets on the IOTA Network. Certain assumptions apply to `Coin` objects as per the [Coin Standard](../standards/coin.mdx): - All `Coin` objects can be freely transferred by the owner of this object. - Only the owner of the `Coin` object can interact with it. -- The only restriction that can be added to a `Coin` object is the optional blocking of transfers for addresses on a `DenyList`. This only applies to `Coin` objects that have been instantiated as [Regulated Coins](../../standards/coin.mdx#regulated-coins). +- The only restriction that can be added to a `Coin` object is the optional blocking of transfers for addresses on a `DenyList`. This only applies to `Coin` objects that have been instantiated as [Regulated Coins](../standards/coin.mdx#regulated-coins). * It is not possible to add other limiting functionality to `Coin` objects directly, like vesting or time-locks; this can only be done by wrapping the unrestricted `Coin` object within another restricting object. It's safe to assume that if you receive a `Coin` object, you can use it without limitations. - A `Coin` is tied to a `CoinMetadata` object containing `name`, `symbol`, `decimals`, `description`, and an `icon_url` - The holder of the TreasuryCap handles administrative tasks of a Coin like minting new tokens or changing metadata; Without a `TreasuryCap` these actions can no longer be performed. @@ -94,4 +94,4 @@ Gas fees to interact with custom tokens are paid in IOTA, like any other interac #### Integration -Depending on your preferences, you can integrate your exchange in multiple ways. You can go from a low-level implementation to directly talking to a node's RPC server or use one of our SDKs (the official TypeScript or Rust SDK is recommended). For details on how to integrate, please check out the [Exchange Integration Guide](../operator/exchange-integration.mdx). \ No newline at end of file +Depending on your preferences, you can integrate your exchange in multiple ways. You can go from a low-level implementation to directly talking to a node's RPC server or use one of our SDKs (the official TypeScript or Rust SDK is recommended). For details on how to integrate, please check out the [Exchange Integration Guide](../exchange-integration/exchange-integration.mdx). \ No newline at end of file diff --git a/docs/content/references/iota-api/iota-graphql/reference/api/mutations/execute-transaction-block.mdx b/docs/content/references/iota-api/iota-graphql/reference/api/mutations/execute-transaction-block.mdx index b3785d1f1b3..35f627dcf5f 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/api/mutations/execute-transaction-block.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/api/mutations/execute-transaction-block.mdx @@ -41,18 +41,23 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => Execute a transaction, committing its effects on chain. -- `txBytes` is a `TransactionData` struct that has been BCS-encoded and then Base64-encoded. -- `signatures` are a list of `flag || signature || pubkey` bytes, Base64-encoded. +- `txBytes` is a `TransactionData` struct that has been BCS-encoded and +then Base64-encoded. +- `signatures` are a list of `flag || signature || pubkey` bytes, +Base64-encoded. -Waits until the transaction has reached finality on chain to return its transaction digest, -or returns the error that prevented finality if that was not possible. A transaction is -final when its effects are guaranteed on chain (it cannot be revoked). +Waits until the transaction has reached finality on chain to return its +transaction digest, or returns the error that prevented finality if +that was not possible. A transaction is final when its effects are +guaranteed on chain (it cannot be revoked). -There may be a delay between transaction finality and when GraphQL requests (including the -request that issued the transaction) reflect its effects. As a result, queries that depend -on indexing the state of the chain (e.g. contents of output objects, address-level balance -information at the time of the transaction), must wait for indexing to catch up by polling -for the transaction digest using `Query.transactionBlock`. +There may be a delay between transaction finality and when GraphQL +requests (including the request that issued the transaction) reflect +its effects. As a result, queries that depend on indexing the state +of the chain (e.g. contents of output objects, address-level balance +information at the time of the transaction), must wait for indexing to +catch up by polling for the transaction digest using +`Query.transactionBlock`. ```graphql @@ -84,7 +89,8 @@ executeTransactionBlock( #### [`ExecutionResult`](/references/iota-api/iota-graphql/reference/types/objects/execution-result) > > -> The result of an execution, including errors that occurred during said execution. +> The result of an execution, including errors that occurred during said +> execution. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/api/queries/address.mdx b/docs/content/references/iota-api/iota-graphql/reference/api/queries/address.mdx index de233108207..a8b5592deab 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/api/queries/address.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/api/queries/address.mdx @@ -64,7 +64,8 @@ address( #### [`Address`](/references/iota-api/iota-graphql/reference/types/objects/address) > > -> The 32-byte address that is an account address (corresponding to a public key). +> The 32-byte address that is an account address (corresponding to a public +> key). > diff --git a/docs/content/references/iota-api/iota-graphql/reference/api/queries/available-range.mdx b/docs/content/references/iota-api/iota-graphql/reference/api/queries/available-range.mdx index 1dc7725d825..347ecb7db28 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/api/queries/available-range.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/api/queries/available-range.mdx @@ -55,7 +55,8 @@ availableRange: AvailableRange! #### [`AvailableRange`](/references/iota-api/iota-graphql/reference/types/objects/available-range) > > -> Range of checkpoints that the RPC is guaranteed to produce a consistent response for. +> Range of checkpoints that the RPC is guaranteed to produce a consistent +> response for. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/api/queries/chain-identifier.mdx b/docs/content/references/iota-api/iota-graphql/reference/api/queries/chain-identifier.mdx index 38c33e123b3..511fa33f1a3 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/api/queries/chain-identifier.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/api/queries/chain-identifier.mdx @@ -39,8 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -First four bytes of the network's genesis checkpoint digest (uniquely identifies the -network). +First four bytes of the network's genesis checkpoint digest (uniquely +identifies the network). ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/api/queries/checkpoint.mdx b/docs/content/references/iota-api/iota-graphql/reference/api/queries/checkpoint.mdx index d3cdda2db51..176a84235bd 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/api/queries/checkpoint.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/api/queries/checkpoint.mdx @@ -39,8 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Fetch checkpoint information by sequence number or digest (defaults to the latest available -checkpoint). +Fetch checkpoint information by sequence number or digest (defaults to +the latest available checkpoint). ```graphql @@ -65,8 +65,8 @@ checkpoint( #### [`Checkpoint`](/references/iota-api/iota-graphql/reference/types/objects/checkpoint) > > -> Checkpoints contain finalized transactions and are used for node synchronization -> and global transaction ordering. +> Checkpoints contain finalized transactions and are used for node +> synchronization and global transaction ordering. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/api/queries/coins.mdx b/docs/content/references/iota-api/iota-graphql/reference/api/queries/coins.mdx index c3f065f78a1..91346413293 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/api/queries/coins.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/api/queries/coins.mdx @@ -41,8 +41,9 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => The coin objects that exist in the network. -The type field is a string of the inner type of the coin by which to filter (e.g. -`0x2::iota::IOTA`). If no type is provided, it will default to `0x2::iota::IOTA`. +The type field is a string of the inner type of the coin by which to +filter (e.g. `0x2::iota::IOTA`). If no type is provided, it will +default to `0x2::iota::IOTA`. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/api/queries/epoch.mdx b/docs/content/references/iota-api/iota-graphql/reference/api/queries/epoch.mdx index fcaff3e99c4..22efc426e34 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/api/queries/epoch.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/api/queries/epoch.mdx @@ -64,9 +64,9 @@ epoch( #### [`Epoch`](/references/iota-api/iota-graphql/reference/types/objects/epoch) > > -> Operation of the Iota network is temporally partitioned into non-overlapping epochs, -> and the network aims to keep epochs roughly the same duration as each other. -> During a particular epoch the following data is fixed: +> Operation of the Iota network is temporally partitioned into non-overlapping +> epochs, and the network aims to keep epochs roughly the same duration as +> each other. During a particular epoch the following data is fixed: > > - the protocol version > - the reference gas price diff --git a/docs/content/references/iota-api/iota-graphql/reference/api/queries/object.mdx b/docs/content/references/iota-api/iota-graphql/reference/api/queries/object.mdx index 015aa1a1361..5b928ad3b3f 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/api/queries/object.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/api/queries/object.mdx @@ -39,8 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -The object corresponding to the given address at the (optionally) given version. -When no version is given, the latest version is returned. +The object corresponding to the given address at the (optionally) given +version. When no version is given, the latest version is returned. ```graphql @@ -72,9 +72,10 @@ object( #### [`Object`](/references/iota-api/iota-graphql/reference/types/objects/object) > > -> An object in Iota is a package (set of Move bytecode modules) or object (typed data structure -> with fields) with additional metadata detailing its id, version, transaction digest, owner -> field indicating how this object can be accessed. +> An object in Iota is a package (set of Move bytecode modules) or object +> (typed data structure with fields) with additional metadata detailing its +> id, version, transaction digest, owner field indicating how this object can +> be accessed. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/api/queries/owner.mdx b/docs/content/references/iota-api/iota-graphql/reference/api/queries/owner.mdx index 3abfe0cb124..0f2928288b7 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/api/queries/owner.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/api/queries/owner.mdx @@ -64,9 +64,10 @@ owner( #### [`Owner`](/references/iota-api/iota-graphql/reference/types/objects/owner) > > -> An Owner is an entity that can own an object. Each Owner is identified by a IotaAddress which -> represents either an Address (corresponding to a public key of an account) or an Object, but -> never both (it is not known up-front whether a given Owner is an Address or an Object). +> An Owner is an entity that can own an object. Each Owner is identified by a +> IotaAddress which represents either an Address (corresponding to a public +> key of an account) or an Object, but never both (it is not known up-front +> whether a given Owner is an Address or an Object). > diff --git a/docs/content/references/iota-api/iota-graphql/reference/api/queries/protocol-config.mdx b/docs/content/references/iota-api/iota-graphql/reference/api/queries/protocol-config.mdx index 6921325938b..d6f6866cc1d 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/api/queries/protocol-config.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/api/queries/protocol-config.mdx @@ -39,8 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Fetch the protocol config by protocol version (defaults to the latest protocol -version known to the GraphQL service). +Fetch the protocol config by protocol version (defaults to the latest +protocol version known to the GraphQL service). ```graphql @@ -67,7 +67,8 @@ protocolConfig( > > Constants that control how the chain operates. > -> These can only change during protocol upgrades which happen on epoch boundaries. +> These can only change during protocol upgrades which happen on epoch +> boundaries. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/api/queries/resolve-iotans-address.mdx b/docs/content/references/iota-api/iota-graphql/reference/api/queries/resolve-iotans-address.mdx index 7ce1ddcfa02..6f9f3cedc6a 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/api/queries/resolve-iotans-address.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/api/queries/resolve-iotans-address.mdx @@ -64,7 +64,8 @@ resolveIotansAddress( #### [`Address`](/references/iota-api/iota-graphql/reference/types/objects/address) > > -> The 32-byte address that is an account address (corresponding to a public key). +> The 32-byte address that is an account address (corresponding to a public +> key). > diff --git a/docs/content/references/iota-api/iota-graphql/reference/api/queries/type.mdx b/docs/content/references/iota-api/iota-graphql/reference/api/queries/type.mdx index 7b9b121ba9b..b253a7f53df 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/api/queries/type.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/api/queries/type.mdx @@ -39,8 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Fetch a structured representation of a concrete type, including its layout information. -Fails if the type is malformed. +Fetch a structured representation of a concrete type, including its +layout information. Fails if the type is malformed. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/api/queries/verify-zklogin-signature.mdx b/docs/content/references/iota-api/iota-graphql/reference/api/queries/verify-zklogin-signature.mdx index 5bd3a02204e..de95f8b63bc 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/api/queries/verify-zklogin-signature.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/api/queries/verify-zklogin-signature.mdx @@ -39,17 +39,20 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Verify a zkLogin signature based on the provided transaction or personal message -based on current epoch, chain id, and latest JWKs fetched on-chain. If the -signature is valid, the function returns a `ZkLoginVerifyResult` with success as -true and an empty list of errors. If the signature is invalid, the function returns +Verify a zkLogin signature based on the provided transaction or personal +message based on current epoch, chain id, and latest JWKs fetched +on-chain. If the signature is valid, the function returns a +`ZkLoginVerifyResult` with success as true and an empty list of +errors. If the signature is invalid, the function returns a `ZkLoginVerifyResult` with success as false with a list of errors. -- `bytes` is either the personal message in raw bytes or transaction data bytes in -BCS-encoded and then Base64-encoded. +- `bytes` is either the personal message in raw bytes or transaction +data bytes in BCS-encoded and then Base64-encoded. - `signature` is a serialized zkLogin signature that is Base64-encoded. -- `intentScope` is an enum that specifies the intent scope to be used to parse bytes. -- `author` is the address of the signer of the transaction or personal msg. +- `intentScope` is an enum that specifies the intent scope to be used to +parse bytes. +- `author` is the address of the signer of the transaction or personal +msg. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/enums/address-transaction-block-relationship.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/enums/address-transaction-block-relationship.mdx index 27bf0af0b13..4a0f39c97f2 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/enums/address-transaction-block-relationship.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/enums/address-transaction-block-relationship.mdx @@ -39,7 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -The possible relationship types for a transaction block: sign, sent, received, or paid. +The possible relationship types for a transaction block: sign, sent, +received, or paid. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/enums/feature.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/enums/feature.mdx index 503f2c8c021..dcfce0c2f85 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/enums/feature.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/enums/feature.mdx @@ -39,8 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Groups of features served by the RPC service. The GraphQL Service can be configured to enable -or disable these features. +Groups of features served by the RPC service. The GraphQL Service can be +configured to enable or disable these features. ```graphql @@ -62,7 +62,8 @@ enum Feature { #### [Feature.ANALYTICS](#) > > -> Statistics about how the network was running (TPS, top packages, APY, etc) +> Statistics about how the network was running (TPS, top packages, APY, +> etc) > #### [Feature.COINS](#) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/enums/move-ability.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/enums/move-ability.mdx index 591689f0b43..be5e611d3d8 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/enums/move-ability.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/enums/move-ability.mdx @@ -39,7 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Abilities are keywords in Iota Move that define how types behave at the compiler level. +Abilities are keywords in Iota Move that define how types behave at the +compiler level. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/enums/move-visibility.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/enums/move-visibility.mdx index 748ad09310b..660ebd88bea 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/enums/move-visibility.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/enums/move-visibility.mdx @@ -39,8 +39,9 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -The visibility modifier describes which modules can access this module member. -By default, a module member can be called only within the same module. +The visibility modifier describes which modules can access this module +member. By default, a module member can be called only within the same +module. ```graphql @@ -71,8 +72,9 @@ enum MoveVisibility { #### [MoveVisibility.FRIEND](#) > > -> A friend member can be accessed in the module it is defined in and any other module in -> its package that is explicitly specified in its friend list. +> A friend member can be accessed in the module it is defined in and any +> other module in its package that is explicitly specified in its +> friend list. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/enums/object-kind.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/enums/object-kind.mdx index 4f7d8281e29..54e2732e11d 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/enums/object-kind.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/enums/object-kind.mdx @@ -59,7 +59,8 @@ enum ObjectKind { #### [ObjectKind.NOT_INDEXED](#) > > -> The object is loaded from serialized data, such as the contents of a transaction. +> The object is loaded from serialized data, such as the contents of a +> transaction. > #### [ObjectKind.LIVE](#) @@ -71,15 +72,15 @@ enum ObjectKind { #### [ObjectKind.HISTORICAL](#) > > -> The object is referenced at some version, and thus is fetched from the snapshot or -> historical objects table. +> The object is referenced at some version, and thus is fetched from the +> snapshot or historical objects table. > #### [ObjectKind.WRAPPED_OR_DELETED](#) > > -> The object is deleted or wrapped and only partial information can be loaded from the -> indexer. +> The object is deleted or wrapped and only partial information can be +> loaded from the indexer. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/enums/stake-status.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/enums/stake-status.mdx index 13360d35e7b..1b915340c3a 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/enums/stake-status.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/enums/stake-status.mdx @@ -58,7 +58,8 @@ enum StakeStatus { #### [StakeStatus.ACTIVE](#) > > -> The stake object is active in a staking pool and it is generating rewards. +> The stake object is active in a staking pool and it is generating +> rewards. > #### [StakeStatus.PENDING](#) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/enums/zk-login-intent-scope.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/enums/zk-login-intent-scope.mdx index 80a91083bcf..0b6946cfe7a 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/enums/zk-login-intent-scope.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/enums/zk-login-intent-scope.mdx @@ -39,8 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -An enum that specifies the intent scope to be used to parse the bytes for signature -verification. +An enum that specifies the intent scope to be used to parse the bytes for +signature verification. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/inputs/checkpoint-id.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/inputs/checkpoint-id.mdx index 845a15fa6b7..21afe40362d 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/inputs/checkpoint-id.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/inputs/checkpoint-id.mdx @@ -39,7 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Filter either by the digest, or the sequence number, or neither, to get the latest checkpoint. +Filter either by the digest, or the sequence number, or neither, to get the +latest checkpoint. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/inputs/dynamic-field-name.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/inputs/dynamic-field-name.mdx index 47900ff9a24..032d1c0cb25 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/inputs/dynamic-field-name.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/inputs/dynamic-field-name.mdx @@ -58,7 +58,8 @@ input DynamicFieldName { > > > The string type of the DynamicField's 'name' field. -> A string representation of a Move primitive like 'u64', or a struct type like '0x2::kiosk::Listing' +> A string representation of a Move primitive like 'u64', or a struct type +> like '0x2::kiosk::Listing' > #### [DynamicFieldName.bcs](#)[`Base64!`](/references/iota-api/iota-graphql/reference/types/scalars/base-64) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/inputs/object-filter.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/inputs/object-filter.mdx index bb7ab55a908..4b1e51caefc 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/inputs/object-filter.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/inputs/object-filter.mdx @@ -39,12 +39,13 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Constrains the set of objects returned. All filters are optional, and the resulting set of -objects are ones whose +Constrains the set of objects returned. All filters are optional, and the +resulting set of objects are ones whose - Type matches the `type` filter, - AND, whose owner matches the `owner` filter, -- AND, whose ID is in `objectIds` OR whose ID and version is in `objectKeys`. +- AND, whose ID is in `objectIds` OR whose ID and version is in +`objectKeys`. ```graphql @@ -64,14 +65,15 @@ input ObjectFilter { #### [ObjectFilter.type](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> This field is used to specify the type of objects that should be included in the query -> results. +> This field is used to specify the type of objects that should be +> included in the query results. > -> Objects can be filtered by their type's package, package::module, or their fully qualified -> type name. +> Objects can be filtered by their type's package, package::module, or +> their fully qualified type name. > -> Generic types can be queried by either the generic type name, e.g. `0x2::coin::Coin`, or by -> the full type name, such as `0x2::coin::Coin<0x2::iota::IOTA>`. +> Generic types can be queried by either the generic type name, e.g. +> `0x2::coin::Coin`, or by the full type name, such as +> `0x2::coin::Coin<0x2::iota::IOTA>`. > #### [ObjectFilter.owner](#)[`IotaAddress`](/references/iota-api/iota-graphql/reference/types/scalars/iota-address) @@ -89,7 +91,8 @@ input ObjectFilter { #### [ObjectFilter.objectKeys](#)[`[ObjectKey!]`](/references/iota-api/iota-graphql/reference/types/inputs/object-key) > > -> Filter for live or potentially historical objects by their ID and version. +> Filter for live or potentially historical objects by their ID and +> version. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/inputs/transaction-block-filter.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/inputs/transaction-block-filter.mdx index a9b45e14983..15d707446fe 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/inputs/transaction-block-filter.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/inputs/transaction-block-filter.mdx @@ -71,7 +71,8 @@ input TransactionBlockFilter { #### [TransactionBlockFilter.kind](#)[`TransactionBlockKindInput`](/references/iota-api/iota-graphql/reference/types/enums/transaction-block-kind-input) > > -> An input filter selecting for either system or programmable transactions. +> An input filter selecting for either system or programmable +> transactions. > #### [TransactionBlockFilter.afterCheckpoint](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/inputs/transaction-metadata.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/inputs/transaction-metadata.mdx index 21967d1e1af..a36b97d4795 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/inputs/transaction-metadata.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/inputs/transaction-metadata.mdx @@ -40,10 +40,10 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => The optional extra data a user can provide to a transaction dry run. -`sender` defaults to `0x0`. If gasObjects` is not present, or is an empty list, -it is substituted with a mock Coin object, `gasPrice` defaults to the reference -gas price, `gasBudget` defaults to the max gas budget and `gasSponsor` defaults -to the sender. +`sender` defaults to `0x0`. If gasObjects` is not present, or is an empty +list, it is substituted with a mock Coin object, `gasPrice` defaults to the +reference gas price, `gasBudget` defaults to the max gas budget and +`gasSponsor` defaults to the sender. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/interfaces/imove-object.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/interfaces/imove-object.mdx index c573210cb2c..7ccfb5076ce 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/interfaces/imove-object.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/interfaces/imove-object.mdx @@ -39,8 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -This interface is implemented by types that represent a Move object on-chain (A Move value whose -type has `key`). +This interface is implemented by types that represent a Move object on-chain +(A Move value whose type has `key`). ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/interfaces/iobject.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/interfaces/iobject.mdx index 0d794a32bee..bbbfe6662ad 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/interfaces/iobject.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/interfaces/iobject.mdx @@ -39,8 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Interface implemented by on-chain values that are addressable by an ID (also referred to as its -address). This includes Move objects and packages. +Interface implemented by on-chain values that are addressable by an ID (also +referred to as its address). This includes Move objects and packages. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/interfaces/iowner.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/interfaces/iowner.mdx index 0fc124cb8b8..99de4d0c71f 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/interfaces/iowner.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/interfaces/iowner.mdx @@ -39,10 +39,11 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Interface implemented by GraphQL types representing entities that can own objects. Object owners -are identified by an address which can represent either the public key of an account or another -object. The same address can only refer to an account or an object, never both, but it is not -possible to know which up-front. +Interface implemented by GraphQL types representing entities that can own +objects. Object owners are identified by an address which can represent +either the public key of an account or another object. The same address can +only refer to an account or an object, never both, but it is not possible to +know which up-front. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/active-jwk.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/active-jwk.mdx index 204d0178326..9da0e7e1b13 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/active-jwk.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/active-jwk.mdx @@ -68,7 +68,8 @@ type ActiveJwk { #### [ActiveJwk.kid](#)[`String!`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> The string (Key ID) that identifies the JWK among a set of JWKs, (RFC 7517, Section 4.5). +> The string (Key ID) that identifies the JWK among a set of JWKs, (RFC +> 7517, Section 4.5). > #### [ActiveJwk.kty](#)[`String!`](/references/iota-api/iota-graphql/reference/types/scalars/string) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/address-owner.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/address-owner.mdx index 640fc5c340a..7234d059605 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/address-owner.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/address-owner.mdx @@ -41,7 +41,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => An address-owned object is owned by a specific 32-byte address that is either an account address (derived from a particular signature scheme) or -an object ID. An address-owned object is accessible only to its owner and no others. +an object ID. An address-owned object is accessible only to its owner and no +others. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/address.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/address.mdx index 7091154a6ad..512917bfe0d 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/address.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/address.mdx @@ -39,7 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -The 32-byte address that is an account address (corresponding to a public key). +The 32-byte address that is an account address (corresponding to a public +key). ```graphql @@ -142,8 +143,8 @@ type Address implements IOwner { #### [Address.balance](#)[`Balance`](/references/iota-api/iota-graphql/reference/types/objects/balance) > > -> Total balance of all coins with marker type owned by this address. If type is not supplied, -> it defaults to `0x2::iota::IOTA`. +> Total balance of all coins with marker type owned by this address. If +> type is not supplied, it defaults to `0x2::iota::IOTA`. > ##### [Address.balance.type](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > @@ -183,7 +184,8 @@ type Address implements IOwner { > > The coin objects for this address. > -> `type` is a filter on the coin's type parameter, defaulting to `0x2::iota::IOTA`. +> `type` is a filter on the coin's type parameter, defaulting to +> `0x2::iota::IOTA`. > ##### [Address.coins.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -245,7 +247,8 @@ type Address implements IOwner { #### [Address.defaultIotansName](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> The domain explicitly configured as the default domain pointing to this address. +> The domain explicitly configured as the default domain pointing to this +> address. > ##### [Address.defaultIotansName.format](#)[`DomainFormat`](/references/iota-api/iota-graphql/reference/types/enums/domain-format) > > @@ -255,8 +258,8 @@ type Address implements IOwner { #### [Address.iotansRegistrations](#)[`IotansRegistrationConnection!`](/references/iota-api/iota-graphql/reference/types/objects/iotans-registration-connection) > > -> The IotansRegistration NFTs owned by this address. These grant the owner the capability to -> manage the associated domain. +> The IotansRegistration NFTs owned by this address. These grant the owner +> the capability to manage the associated domain. > ##### [Address.iotansRegistrations.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -284,8 +287,9 @@ type Address implements IOwner { #### [Address.transactionBlocks](#)[`TransactionBlockConnection!`](/references/iota-api/iota-graphql/reference/types/objects/transaction-block-connection) > > -> Similar behavior to the `transactionBlocks` in Query but supporting the additional -> `AddressTransactionBlockRelationship` filter, which defaults to `SIGN`. +> Similar behavior to the `transactionBlocks` in Query but supporting the +> additional `AddressTransactionBlockRelationship` filter, which +> defaults to `SIGN`. > ##### [Address.transactionBlocks.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -327,10 +331,11 @@ type Address implements IOwner { #### [`IOwner`](/references/iota-api/iota-graphql/reference/types/interfaces/iowner) > > -> Interface implemented by GraphQL types representing entities that can own objects. Object owners -> are identified by an address which can represent either the public key of an account or another -> object. The same address can only refer to an account or an object, never both, but it is not -> possible to know which up-front. +> Interface implemented by GraphQL types representing entities that can own +> objects. Object owners are identified by an address which can represent +> either the public key of an account or another object. The same address can +> only refer to an account or an object, never both, but it is not possible to +> know which up-front. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/available-range.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/available-range.mdx index 70a31a9cffc..fba988ca579 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/available-range.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/available-range.mdx @@ -39,7 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Range of checkpoints that the RPC is guaranteed to produce a consistent response for. +Range of checkpoints that the RPC is guaranteed to produce a consistent +response for. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/balance-change.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/balance-change.mdx index 01a2d3d8288..4331047e1d7 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/balance-change.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/balance-change.mdx @@ -39,7 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Effects to the balance (sum of coin values per coin type) owned by an address or object. +Effects to the balance (sum of coin values per coin type) owned by an +address or object. ```graphql @@ -64,7 +65,8 @@ type BalanceChange { #### [BalanceChange.coinType](#)[`MoveType`](/references/iota-api/iota-graphql/reference/types/objects/move-type) > > -> The inner type of the coin whose balance has changed (e.g. `0x2::iota::IOTA`). +> The inner type of the coin whose balance has changed (e.g. +> `0x2::iota::IOTA`). > #### [BalanceChange.amount](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/change-epoch-transaction.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/change-epoch-transaction.mdx index 98c2df3b675..b9247ac41bf 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/change-epoch-transaction.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/change-epoch-transaction.mdx @@ -39,9 +39,10 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -A system transaction that updates epoch information on-chain (increments the current epoch). -Executed by the system once per epoch, without using gas. Epoch change transactions cannot be -submitted by users, because validators will refuse to sign them. +A system transaction that updates epoch information on-chain (increments the +current epoch). Executed by the system once per epoch, without using gas. +Epoch change transactions cannot be submitted by users, because validators +will refuse to sign them. This transaction kind is deprecated in favour of `EndOfEpochTransaction`. @@ -84,26 +85,29 @@ type ChangeEpochTransaction { #### [ChangeEpochTransaction.storageCharge](#)[`BigInt!`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> The total amount of gas charged for storage during the previous epoch (in MICROS). +> The total amount of gas charged for storage during the previous epoch +> (in MICROS). > #### [ChangeEpochTransaction.computationCharge](#)[`BigInt!`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> The total amount of gas charged for computation during the previous epoch (in MICROS). +> The total amount of gas charged for computation during the previous +> epoch (in MICROS). > #### [ChangeEpochTransaction.storageRebate](#)[`BigInt!`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> The IOTA returned to transaction senders for cleaning up objects (in MICROS). +> The IOTA returned to transaction senders for cleaning up objects (in +> MICROS). > #### [ChangeEpochTransaction.nonRefundableStorageFee](#)[`BigInt!`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> The total gas retained from storage fees, that will not be returned by storage rebates when -> the relevant objects are cleaned up (in MICROS). +> The total gas retained from storage fees, that will not be returned by +> storage rebates when the relevant objects are cleaned up (in MICROS). > #### [ChangeEpochTransaction.startTimestamp](#)[`DateTime!`](/references/iota-api/iota-graphql/reference/types/scalars/date-time) @@ -115,9 +119,9 @@ type ChangeEpochTransaction { #### [ChangeEpochTransaction.systemPackages](#)[`MovePackageConnection!`](/references/iota-api/iota-graphql/reference/types/objects/move-package-connection) > > -> System packages (specifically framework and move stdlib) that are written before the new -> epoch starts, to upgrade them on-chain. Validators write these packages out when running the -> transaction. +> System packages (specifically framework and move stdlib) that are +> written before the new epoch starts, to upgrade them on-chain. +> Validators write these packages out when running the transaction. > ##### [ChangeEpochTransaction.systemPackages.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/checkpoint.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/checkpoint.mdx index 5fde8b72843..c0b31a03665 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/checkpoint.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/checkpoint.mdx @@ -39,8 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Checkpoints contain finalized transactions and are used for node synchronization -and global transaction ordering. +Checkpoints contain finalized transactions and are used for node +synchronization and global transaction ordering. ```graphql @@ -71,30 +71,32 @@ type Checkpoint { #### [Checkpoint.digest](#)[`String!`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> A 32-byte hash that uniquely identifies the checkpoint contents, encoded in Base58. This -> hash can be used to verify checkpoint contents by checking signatures against the committee, -> Hashing contents to match digest, and checking that the previous checkpoint digest matches. +> A 32-byte hash that uniquely identifies the checkpoint contents, encoded +> in Base58. This hash can be used to verify checkpoint contents by +> checking signatures against the committee, Hashing contents to match +> digest, and checking that the previous checkpoint digest matches. > #### [Checkpoint.sequenceNumber](#)[`Int!`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > -> This checkpoint's position in the total order of finalized checkpoints, agreed upon by -> consensus. +> This checkpoint's position in the total order of finalized checkpoints, +> agreed upon by consensus. > #### [Checkpoint.timestamp](#)[`DateTime!`](/references/iota-api/iota-graphql/reference/types/scalars/date-time) > > -> The timestamp at which the checkpoint is agreed to have happened according to consensus. -> Transactions that access time in this checkpoint will observe this timestamp. +> The timestamp at which the checkpoint is agreed to have happened +> according to consensus. Transactions that access time in this +> checkpoint will observe this timestamp. > #### [Checkpoint.validatorSignatures](#)[`Base64!`](/references/iota-api/iota-graphql/reference/types/scalars/base-64) > > -> This is an aggregation of signatures from a quorum of validators for the checkpoint -> proposal. +> This is an aggregation of signatures from a quorum of validators for the +> checkpoint proposal. > #### [Checkpoint.previousCheckpointDigest](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) @@ -106,15 +108,17 @@ type Checkpoint { #### [Checkpoint.networkTotalTransactions](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > -> The total number of transaction blocks in the network by the end of this checkpoint. +> The total number of transaction blocks in the network by the end of this +> checkpoint. > #### [Checkpoint.rollingGasSummary](#)[`GasCostSummary`](/references/iota-api/iota-graphql/reference/types/objects/gas-cost-summary) > > -> The computation cost, storage cost, storage rebate, and non-refundable storage fee -> accumulated during this epoch, up to and including this checkpoint. These values increase -> monotonically across checkpoints in the same epoch, and reset on epoch boundaries. +> The computation cost, storage cost, storage rebate, and non-refundable +> storage fee accumulated during this epoch, up to and including this +> checkpoint. These values increase monotonically across checkpoints +> in the same epoch, and reset on epoch boundaries. > #### [Checkpoint.epoch](#)[`Epoch`](/references/iota-api/iota-graphql/reference/types/objects/epoch) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/coin-metadata.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/coin-metadata.mdx index 0884af365a7..d77e94f2f97 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/coin-metadata.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/coin-metadata.mdx @@ -169,8 +169,8 @@ type CoinMetadata implements IMoveObject, IObject, IOwner { #### [CoinMetadata.balance](#)[`Balance`](/references/iota-api/iota-graphql/reference/types/objects/balance) > > -> Total balance of all coins with marker type owned by this object. If type is not supplied, -> it defaults to `0x2::iota::IOTA`. +> Total balance of all coins with marker type owned by this object. If +> type is not supplied, it defaults to `0x2::iota::IOTA`. > ##### [CoinMetadata.balance.type](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > @@ -210,7 +210,8 @@ type CoinMetadata implements IMoveObject, IObject, IOwner { > > The coin objects for this object. > -> `type` is a filter on the coin's type parameter, defaulting to `0x2::iota::IOTA`. +> `type` is a filter on the coin's type parameter, defaulting to +> `0x2::iota::IOTA`. > ##### [CoinMetadata.coins.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -272,7 +273,8 @@ type CoinMetadata implements IMoveObject, IObject, IOwner { #### [CoinMetadata.defaultIotansName](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> The domain explicitly configured as the default domain pointing to this object. +> The domain explicitly configured as the default domain pointing to this +> object. > ##### [CoinMetadata.defaultIotansName.format](#)[`DomainFormat`](/references/iota-api/iota-graphql/reference/types/enums/domain-format) > > @@ -282,8 +284,8 @@ type CoinMetadata implements IMoveObject, IObject, IOwner { #### [CoinMetadata.iotansRegistrations](#)[`IotansRegistrationConnection!`](/references/iota-api/iota-graphql/reference/types/objects/iotans-registration-connection) > > -> The IotansRegistration NFTs owned by this object. These grant the owner the capability to -> manage the associated domain. +> The IotansRegistration NFTs owned by this object. These grant the owner +> the capability to manage the associated domain. > ##### [CoinMetadata.iotansRegistrations.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -317,19 +319,22 @@ type CoinMetadata implements IMoveObject, IObject, IOwner { #### [CoinMetadata.status](#)[`ObjectKind!`](/references/iota-api/iota-graphql/reference/types/enums/object-kind) > > -> The current status of the object as read from the off-chain store. The possible states are: -> NOT_INDEXED, the object is loaded from serialized data, such as the contents of a genesis or -> system package upgrade transaction. LIVE, the version returned is the most recent for the -> object, and it is not deleted or wrapped at that version. HISTORICAL, the object was -> referenced at a specific version or checkpoint, so is fetched from historical tables and may -> not be the latest version of the object. WRAPPED_OR_DELETED, the object is deleted or -> wrapped and only partial information can be loaded." +> The current status of the object as read from the off-chain store. The +> possible states are: NOT_INDEXED, the object is loaded from +> serialized data, such as the contents of a genesis or system package +> upgrade transaction. LIVE, the version returned is the most recent for +> the object, and it is not deleted or wrapped at that version. +> HISTORICAL, the object was referenced at a specific version or +> checkpoint, so is fetched from historical tables and may not be the +> latest version of the object. WRAPPED_OR_DELETED, the object is deleted +> or wrapped and only partial information can be loaded." > #### [CoinMetadata.digest](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> 32-byte hash that identifies the object's contents, encoded as a Base58 string. +> 32-byte hash that identifies the object's contents, encoded as a Base58 +> string. > #### [CoinMetadata.owner](#)[`ObjectOwner`](/references/iota-api/iota-graphql/reference/types/unions/object-owner) @@ -347,8 +352,9 @@ type CoinMetadata implements IMoveObject, IObject, IOwner { #### [CoinMetadata.storageRebate](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> The amount of IOTA we would rebate if this object gets deleted or mutated. This number is -> recalculated based on the present storage gas price. +> The amount of IOTA we would rebate if this object gets deleted or +> mutated. This number is recalculated based on the present storage +> gas price. > #### [CoinMetadata.receivedTransactionBlocks](#)[`TransactionBlockConnection!`](/references/iota-api/iota-graphql/reference/types/objects/transaction-block-connection) @@ -394,36 +400,37 @@ type CoinMetadata implements IMoveObject, IObject, IOwner { #### [CoinMetadata.contents](#)[`MoveValue`](/references/iota-api/iota-graphql/reference/types/objects/move-value) > > -> Displays the contents of the Move object in a JSON string and through GraphQL types. Also -> provides the flat representation of the type signature, and the BCS of the corresponding -> data. +> Displays the contents of the Move object in a JSON string and through +> GraphQL types. Also provides the flat representation of the type +> signature, and the BCS of the corresponding data. > #### [CoinMetadata.hasPublicTransfer](#)[`Boolean!`](/references/iota-api/iota-graphql/reference/types/scalars/boolean) > > -> Determines whether a transaction can transfer this object, using the TransferObjects -> transaction command or `iota::transfer::public_transfer`, both of which require the object to +> Determines whether a transaction can transfer this object, using the +> TransferObjects transaction command or +> `iota::transfer::public_transfer`, both of which require the object to > have the `key` and `store` abilities. > #### [CoinMetadata.display](#)[`[DisplayEntry!]`](/references/iota-api/iota-graphql/reference/types/objects/display-entry) > > -> The set of named templates defined on-chain for the type of this object, to be handled -> off-chain. The server substitutes data from the object into these templates to generate a -> display string per template. +> The set of named templates defined on-chain for the type of this object, +> to be handled off-chain. The server substitutes data from the object +> into these templates to generate a display string per template. > #### [CoinMetadata.dynamicField](#)[`DynamicField`](/references/iota-api/iota-graphql/reference/types/objects/dynamic-field) > > -> Access a dynamic field on an object using its name. Names are arbitrary Move values whose -> type have `copy`, `drop`, and `store`, and are specified using their type, and their BCS -> contents, Base64 encoded. +> Access a dynamic field on an object using its name. Names are arbitrary +> Move values whose type have `copy`, `drop`, and `store`, and are +> specified using their type, and their BCS contents, Base64 encoded. > -> Dynamic fields on wrapped objects can be accessed by using the same API under the Owner -> type. +> Dynamic fields on wrapped objects can be accessed by using the same API +> under the Owner type. > ##### [CoinMetadata.dynamicField.name](#)[`DynamicFieldName!`](/references/iota-api/iota-graphql/reference/types/inputs/dynamic-field-name) > > @@ -433,13 +440,14 @@ type CoinMetadata implements IMoveObject, IObject, IOwner { #### [CoinMetadata.dynamicObjectField](#)[`DynamicField`](/references/iota-api/iota-graphql/reference/types/objects/dynamic-field) > > -> Access a dynamic object field on an object using its name. Names are arbitrary Move values -> whose type have `copy`, `drop`, and `store`, and are specified using their type, and their -> BCS contents, Base64 encoded. The value of a dynamic object field can also be accessed +> Access a dynamic object field on an object using its name. Names are +> arbitrary Move values whose type have `copy`, `drop`, and `store`, +> and are specified using their type, and their BCS contents, Base64 +> encoded. The value of a dynamic object field can also be accessed > off-chain directly via its address (e.g. using `Query.object`). > -> Dynamic fields on wrapped objects can be accessed by using the same API under the Owner -> type. +> Dynamic fields on wrapped objects can be accessed by using the same API +> under the Owner type. > ##### [CoinMetadata.dynamicObjectField.name](#)[`DynamicFieldName!`](/references/iota-api/iota-graphql/reference/types/inputs/dynamic-field-name) > > @@ -451,8 +459,8 @@ type CoinMetadata implements IMoveObject, IObject, IOwner { > > The dynamic fields and dynamic object fields on an object. > -> Dynamic fields on wrapped objects can be accessed by using the same API under the Owner -> type. +> Dynamic fields on wrapped objects can be accessed by using the same API +> under the Owner type. > ##### [CoinMetadata.dynamicFields.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -518,24 +526,25 @@ type CoinMetadata implements IMoveObject, IObject, IOwner { #### [`IMoveObject`](/references/iota-api/iota-graphql/reference/types/interfaces/imove-object) > > -> This interface is implemented by types that represent a Move object on-chain (A Move value whose -> type has `key`). +> This interface is implemented by types that represent a Move object on-chain +> (A Move value whose type has `key`). > #### [`IObject`](/references/iota-api/iota-graphql/reference/types/interfaces/iobject) > > -> Interface implemented by on-chain values that are addressable by an ID (also referred to as its -> address). This includes Move objects and packages. +> Interface implemented by on-chain values that are addressable by an ID (also +> referred to as its address). This includes Move objects and packages. > #### [`IOwner`](/references/iota-api/iota-graphql/reference/types/interfaces/iowner) > > -> Interface implemented by GraphQL types representing entities that can own objects. Object owners -> are identified by an address which can represent either the public key of an account or another -> object. The same address can only refer to an account or an object, never both, but it is not -> possible to know which up-front. +> Interface implemented by GraphQL types representing entities that can own +> objects. Object owners are identified by an address which can represent +> either the public key of an account or another object. The same address can +> only refer to an account or an object, never both, but it is not possible to +> know which up-front. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/coin.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/coin.mdx index ecb4196dee2..d2ab659e607 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/coin.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/coin.mdx @@ -164,8 +164,8 @@ type Coin implements IMoveObject, IObject, IOwner { #### [Coin.balance](#)[`Balance`](/references/iota-api/iota-graphql/reference/types/objects/balance) > > -> Total balance of all coins with marker type owned by this object. If type is not supplied, -> it defaults to `0x2::iota::IOTA`. +> Total balance of all coins with marker type owned by this object. If +> type is not supplied, it defaults to `0x2::iota::IOTA`. > ##### [Coin.balance.type](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > @@ -205,7 +205,8 @@ type Coin implements IMoveObject, IObject, IOwner { > > The coin objects for this object. > -> `type` is a filter on the coin's type parameter, defaulting to `0x2::iota::IOTA`. +> `type` is a filter on the coin's type parameter, defaulting to +> `0x2::iota::IOTA`. > ##### [Coin.coins.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -267,7 +268,8 @@ type Coin implements IMoveObject, IObject, IOwner { #### [Coin.defaultIotansName](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> The domain explicitly configured as the default domain pointing to this object. +> The domain explicitly configured as the default domain pointing to this +> object. > ##### [Coin.defaultIotansName.format](#)[`DomainFormat`](/references/iota-api/iota-graphql/reference/types/enums/domain-format) > > @@ -277,8 +279,8 @@ type Coin implements IMoveObject, IObject, IOwner { #### [Coin.iotansRegistrations](#)[`IotansRegistrationConnection!`](/references/iota-api/iota-graphql/reference/types/objects/iotans-registration-connection) > > -> The IotansRegistration NFTs owned by this object. These grant the owner the capability to -> manage the associated domain. +> The IotansRegistration NFTs owned by this object. These grant the owner +> the capability to manage the associated domain. > ##### [Coin.iotansRegistrations.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -312,19 +314,22 @@ type Coin implements IMoveObject, IObject, IOwner { #### [Coin.status](#)[`ObjectKind!`](/references/iota-api/iota-graphql/reference/types/enums/object-kind) > > -> The current status of the object as read from the off-chain store. The possible states are: -> NOT_INDEXED, the object is loaded from serialized data, such as the contents of a genesis or -> system package upgrade transaction. LIVE, the version returned is the most recent for the -> object, and it is not deleted or wrapped at that version. HISTORICAL, the object was -> referenced at a specific version or checkpoint, so is fetched from historical tables and may -> not be the latest version of the object. WRAPPED_OR_DELETED, the object is deleted or -> wrapped and only partial information can be loaded." +> The current status of the object as read from the off-chain store. The +> possible states are: NOT_INDEXED, the object is loaded from +> serialized data, such as the contents of a genesis or system package +> upgrade transaction. LIVE, the version returned is the most recent for +> the object, and it is not deleted or wrapped at that version. +> HISTORICAL, the object was referenced at a specific version or +> checkpoint, so is fetched from historical tables and may not be the +> latest version of the object. WRAPPED_OR_DELETED, the object is deleted +> or wrapped and only partial information can be loaded." > #### [Coin.digest](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> 32-byte hash that identifies the object's contents, encoded as a Base58 string. +> 32-byte hash that identifies the object's contents, encoded as a Base58 +> string. > #### [Coin.owner](#)[`ObjectOwner`](/references/iota-api/iota-graphql/reference/types/unions/object-owner) @@ -342,8 +347,9 @@ type Coin implements IMoveObject, IObject, IOwner { #### [Coin.storageRebate](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> The amount of IOTA we would rebate if this object gets deleted or mutated. This number is -> recalculated based on the present storage gas price. +> The amount of IOTA we would rebate if this object gets deleted or +> mutated. This number is recalculated based on the present storage +> gas price. > #### [Coin.receivedTransactionBlocks](#)[`TransactionBlockConnection!`](/references/iota-api/iota-graphql/reference/types/objects/transaction-block-connection) @@ -389,36 +395,37 @@ type Coin implements IMoveObject, IObject, IOwner { #### [Coin.contents](#)[`MoveValue`](/references/iota-api/iota-graphql/reference/types/objects/move-value) > > -> Displays the contents of the Move object in a JSON string and through GraphQL types. Also -> provides the flat representation of the type signature, and the BCS of the corresponding -> data. +> Displays the contents of the Move object in a JSON string and through +> GraphQL types. Also provides the flat representation of the type +> signature, and the BCS of the corresponding data. > #### [Coin.hasPublicTransfer](#)[`Boolean!`](/references/iota-api/iota-graphql/reference/types/scalars/boolean) > > -> Determines whether a transaction can transfer this object, using the TransferObjects -> transaction command or `iota::transfer::public_transfer`, both of which require the object to +> Determines whether a transaction can transfer this object, using the +> TransferObjects transaction command or +> `iota::transfer::public_transfer`, both of which require the object to > have the `key` and `store` abilities. > #### [Coin.display](#)[`[DisplayEntry!]`](/references/iota-api/iota-graphql/reference/types/objects/display-entry) > > -> The set of named templates defined on-chain for the type of this object, to be handled -> off-chain. The server substitutes data from the object into these templates to generate a -> display string per template. +> The set of named templates defined on-chain for the type of this object, +> to be handled off-chain. The server substitutes data from the object +> into these templates to generate a display string per template. > #### [Coin.dynamicField](#)[`DynamicField`](/references/iota-api/iota-graphql/reference/types/objects/dynamic-field) > > -> Access a dynamic field on an object using its name. Names are arbitrary Move values whose -> type have `copy`, `drop`, and `store`, and are specified using their type, and their BCS -> contents, Base64 encoded. +> Access a dynamic field on an object using its name. Names are arbitrary +> Move values whose type have `copy`, `drop`, and `store`, and are +> specified using their type, and their BCS contents, Base64 encoded. > -> Dynamic fields on wrapped objects can be accessed by using the same API under the Owner -> type. +> Dynamic fields on wrapped objects can be accessed by using the same API +> under the Owner type. > ##### [Coin.dynamicField.name](#)[`DynamicFieldName!`](/references/iota-api/iota-graphql/reference/types/inputs/dynamic-field-name) > > @@ -428,13 +435,14 @@ type Coin implements IMoveObject, IObject, IOwner { #### [Coin.dynamicObjectField](#)[`DynamicField`](/references/iota-api/iota-graphql/reference/types/objects/dynamic-field) > > -> Access a dynamic object field on an object using its name. Names are arbitrary Move values -> whose type have `copy`, `drop`, and `store`, and are specified using their type, and their -> BCS contents, Base64 encoded. The value of a dynamic object field can also be accessed +> Access a dynamic object field on an object using its name. Names are +> arbitrary Move values whose type have `copy`, `drop`, and `store`, +> and are specified using their type, and their BCS contents, Base64 +> encoded. The value of a dynamic object field can also be accessed > off-chain directly via its address (e.g. using `Query.object`). > -> Dynamic fields on wrapped objects can be accessed by using the same API under the Owner -> type. +> Dynamic fields on wrapped objects can be accessed by using the same API +> under the Owner type. > ##### [Coin.dynamicObjectField.name](#)[`DynamicFieldName!`](/references/iota-api/iota-graphql/reference/types/inputs/dynamic-field-name) > > @@ -446,8 +454,8 @@ type Coin implements IMoveObject, IObject, IOwner { > > The dynamic fields and dynamic object fields on an object. > -> Dynamic fields on wrapped objects can be accessed by using the same API under the Owner -> type. +> Dynamic fields on wrapped objects can be accessed by using the same API +> under the Owner type. > ##### [Coin.dynamicFields.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -483,24 +491,25 @@ type Coin implements IMoveObject, IObject, IOwner { #### [`IMoveObject`](/references/iota-api/iota-graphql/reference/types/interfaces/imove-object) > > -> This interface is implemented by types that represent a Move object on-chain (A Move value whose -> type has `key`). +> This interface is implemented by types that represent a Move object on-chain +> (A Move value whose type has `key`). > #### [`IObject`](/references/iota-api/iota-graphql/reference/types/interfaces/iobject) > > -> Interface implemented by on-chain values that are addressable by an ID (also referred to as its -> address). This includes Move objects and packages. +> Interface implemented by on-chain values that are addressable by an ID (also +> referred to as its address). This includes Move objects and packages. > #### [`IOwner`](/references/iota-api/iota-graphql/reference/types/interfaces/iowner) > > -> Interface implemented by GraphQL types representing entities that can own objects. Object owners -> are identified by an address which can represent either the public key of an account or another -> object. The same address can only refer to an account or an object, never both, but it is not -> possible to know which up-front. +> Interface implemented by GraphQL types representing entities that can own +> objects. Object owners are identified by an address which can represent +> either the public key of an account or another object. The same address can +> only refer to an account or an object, never both, but it is not possible to +> know which up-front. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/consensus-commit-prologue-transaction.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/consensus-commit-prologue-transaction.mdx index 5c89ca67355..b70214cebd6 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/consensus-commit-prologue-transaction.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/consensus-commit-prologue-transaction.mdx @@ -39,8 +39,9 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -System transaction that runs at the beginning of a checkpoint, and is responsible for setting -the current value of the clock, based on the timestamp from consensus. +System transaction that runs at the beginning of a checkpoint, and is +responsible for setting the current value of the clock, based on the +timestamp from consensus. ```graphql @@ -78,8 +79,8 @@ type ConsensusCommitPrologueTransaction { #### [ConsensusCommitPrologueTransaction.consensusCommitDigest](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> Digest of consensus output, encoded as a Base58 string (only available from V2 of the -> transaction). +> Digest of consensus output, encoded as a Base58 string (only available +> from V2 of the transaction). > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/dry-run-effect.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/dry-run-effect.mdx index d6c5f78bc3a..5240d18074b 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/dry-run-effect.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/dry-run-effect.mdx @@ -57,7 +57,8 @@ type DryRunEffect { #### [DryRunEffect.mutatedReferences](#)[`[DryRunMutation!]`](/references/iota-api/iota-graphql/reference/types/objects/dry-run-mutation) > > -> Changes made to arguments that were mutably borrowed by each command in this transaction. +> Changes made to arguments that were mutably borrowed by each command in +> this transaction. > #### [DryRunEffect.returnValues](#)[`[DryRunReturn!]`](/references/iota-api/iota-graphql/reference/types/objects/dry-run-return) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/dry-run-result.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/dry-run-result.mdx index 26b542464d6..e1376855a6b 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/dry-run-result.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/dry-run-result.mdx @@ -64,8 +64,8 @@ type DryRunResult { #### [DryRunResult.results](#)[`[DryRunEffect!]`](/references/iota-api/iota-graphql/reference/types/objects/dry-run-effect) > > -> The intermediate results for each command of the dry run execution, including -> contents of mutated references and return values. +> The intermediate results for each command of the dry run execution, +> including contents of mutated references and return values. > #### [DryRunResult.transaction](#)[`TransactionBlock`](/references/iota-api/iota-graphql/reference/types/objects/transaction-block) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/dynamic-field.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/dynamic-field.mdx index cd3d7d47b93..f822a8f8e4d 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/dynamic-field.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/dynamic-field.mdx @@ -39,16 +39,17 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Dynamic fields are heterogeneous fields that can be added or removed at runtime, -and can have arbitrary user-assigned names. There are two sub-types of dynamic -fields: +Dynamic fields are heterogeneous fields that can be added or removed at +runtime, and can have arbitrary user-assigned names. There are two sub-types +of dynamic fields: -1) Dynamic Fields can store any value that has the `store` ability, however an object -stored in this kind of field will be considered wrapped and will not be accessible -directly via its ID by external tools (explorers, wallets, etc) accessing storage. -2) Dynamic Object Fields values must be Iota objects (have the `key` and `store` -abilities, and id: UID as the first field), but will still be directly accessible off-chain -via their object ID after being attached. +1) Dynamic Fields can store any value that has the `store` ability, however +an object stored in this kind of field will be considered wrapped and +will not be accessible directly via its ID by external tools (explorers, +wallets, etc) accessing storage. +2) Dynamic Object Fields values must be Iota objects (have the `key` and +`store` abilities, and id: UID as the first field), but will still be +directly accessible off-chain via their object ID after being attached. ```graphql @@ -66,16 +67,18 @@ type DynamicField { #### [DynamicField.name](#)[`MoveValue`](/references/iota-api/iota-graphql/reference/types/objects/move-value) > > -> The string type, data, and serialized value of the DynamicField's 'name' field. -> This field is used to uniquely identify a child of the parent object. +> The string type, data, and serialized value of the DynamicField's 'name' +> field. This field is used to uniquely identify a child of the parent +> object. > #### [DynamicField.value](#)[`DynamicFieldValue`](/references/iota-api/iota-graphql/reference/types/unions/dynamic-field-value) > > > The actual data stored in the dynamic field. -> The returned dynamic field is an object if its return type is MoveObject, -> in which case it is also accessible off-chain via its address. +> The returned dynamic field is an object if its return type is +> MoveObject, in which case it is also accessible off-chain via its +> address. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/end-of-epoch-transaction.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/end-of-epoch-transaction.mdx index ae0e4f8e244..15089ba74e9 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/end-of-epoch-transaction.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/end-of-epoch-transaction.mdx @@ -39,9 +39,10 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -System transaction that supersedes `ChangeEpochTransaction` as the new way to run transactions -at the end of an epoch. Behaves similarly to `ChangeEpochTransaction` but can accommodate other -optional transactions to run at the end of the epoch. +System transaction that supersedes `ChangeEpochTransaction` as the new way +to run transactions at the end of an epoch. Behaves similarly to +`ChangeEpochTransaction` but can accommodate other optional transactions to +run at the end of the epoch. ```graphql @@ -63,7 +64,8 @@ type EndOfEpochTransaction { #### [EndOfEpochTransaction.transactions](#)[`EndOfEpochTransactionKindConnection!`](/references/iota-api/iota-graphql/reference/types/objects/end-of-epoch-transaction-kind-connection) > > -> The list of system transactions that are allowed to run at the end of the epoch. +> The list of system transactions that are allowed to run at the end of +> the epoch. > ##### [EndOfEpochTransaction.transactions.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/epoch.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/epoch.mdx index 5533519e497..1c03e6d3d83 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/epoch.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/epoch.mdx @@ -39,9 +39,9 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Operation of the Iota network is temporally partitioned into non-overlapping epochs, -and the network aims to keep epochs roughly the same duration as each other. -During a particular epoch the following data is fixed: +Operation of the Iota network is temporally partitioned into non-overlapping +epochs, and the network aims to keep epochs roughly the same duration as +each other. During a particular epoch the following data is fixed: - the protocol version - the reference gas price @@ -95,13 +95,15 @@ type Epoch { #### [Epoch.epochId](#)[`Int!`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > -> The epoch's id as a sequence number that starts at 0 and is incremented by one at every epoch change. +> The epoch's id as a sequence number that starts at 0 and is incremented +> by one at every epoch change. > #### [Epoch.referenceGasPrice](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> The minimum gas price that a quorum of validators are guaranteed to sign a transaction for. +> The minimum gas price that a quorum of validators are guaranteed to sign +> a transaction for. > #### [Epoch.validatorSet](#)[`ValidatorSet`](/references/iota-api/iota-graphql/reference/types/objects/validator-set) @@ -176,36 +178,37 @@ type Epoch { #### [Epoch.fundOutflow](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> The storage fee rebates paid to users who deleted the data associated with past -> transactions. +> The storage fee rebates paid to users who deleted the data associated +> with past transactions. > #### [Epoch.protocolConfigs](#)[`ProtocolConfigs!`](/references/iota-api/iota-graphql/reference/types/objects/protocol-configs) > > -> The epoch's corresponding protocol configuration, including the feature flags and the -> configuration options. +> The epoch's corresponding protocol configuration, including the feature +> flags and the configuration options. > #### [Epoch.storageFund](#)[`StorageFund`](/references/iota-api/iota-graphql/reference/types/objects/storage-fund) > > -> IOTA set aside to account for objects stored on-chain, at the start of the epoch. -> This is also used for storage rebates. +> IOTA set aside to account for objects stored on-chain, at the start of +> the epoch. This is also used for storage rebates. > #### [Epoch.safeMode](#)[`SafeMode`](/references/iota-api/iota-graphql/reference/types/objects/safe-mode) > > -> Information about whether this epoch was started in safe mode, which happens if the full epoch -> change logic fails for some reason. +> Information about whether this epoch was started in safe mode, which +> happens if the full epoch change logic fails for some reason. > #### [Epoch.systemStateVersion](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > -> The value of the `version` field of `0x5`, the `0x3::iota::IotaSystemState` object. This -> version changes whenever the fields contained in the system state object (held in a dynamic +> The value of the `version` field of `0x5`, the +> `0x3::iota::IotaSystemState` object. This version changes whenever +> the fields contained in the system state object (held in a dynamic > field attached to `0x5`) change. > @@ -224,8 +227,9 @@ type Epoch { #### [Epoch.liveObjectSetDigest](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> A commitment by the committee at the end of epoch on the contents of the live object set at -> that time. This can be used to verify state snapshots. +> A commitment by the committee at the end of epoch on the contents of the +> live object set at that time. This can be used to verify state +> snapshots. > #### [Epoch.checkpoints](#)[`CheckpointConnection!`](/references/iota-api/iota-graphql/reference/types/objects/checkpoint-connection) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/event.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/event.mdx index c76f1749516..d71f2906681 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/event.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/event.mdx @@ -104,7 +104,8 @@ type Event { > > Representation of a Move value in JSON, where: > -> - Addresses, IDs, and UIDs are represented in canonical form, as JSON strings. +> - Addresses, IDs, and UIDs are represented in canonical form, as JSON +> strings. > - Bools are represented by JSON boolean literals. > - u8, u16, and u32 are represented as JSON numbers. > - u64, u128, and u256 are represented as JSON strings. @@ -112,8 +113,8 @@ type Event { > - Structs are represented by JSON objects. > - Empty optional values are represented by `null`. > -> This form is offered as a less verbose convenience in cases where the layout of the type is -> known by the client. +> This form is offered as a less verbose convenience in cases where the +> layout of the type is known by the client. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/execution-result.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/execution-result.mdx index 19d876b76be..b6b867af41a 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/execution-result.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/execution-result.mdx @@ -39,7 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -The result of an execution, including errors that occurred during said execution. +The result of an execution, including errors that occurred during said +execution. ```graphql @@ -63,9 +64,9 @@ type ExecutionResult { #### [ExecutionResult.effects](#)[`TransactionBlockEffects!`](/references/iota-api/iota-graphql/reference/types/objects/transaction-block-effects) > > -> The effects of the executed transaction. Since the transaction was just executed -> and not indexed yet, fields including `balance_changes`, `timestamp` and `checkpoint` -> are not available. +> The effects of the executed transaction. Since the transaction was just +> executed and not indexed yet, fields including `balance_changes`, +> `timestamp` and `checkpoint` are not available. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/gas-coin.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/gas-coin.mdx index 3bf9c3307e2..fa3f5495507 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/gas-coin.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/gas-coin.mdx @@ -39,8 +39,9 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Access to the gas inputs, after they have been smashed into one coin. The gas coin can only be -used by reference, except for with `TransferObjectsTransaction` that can accept it by value. +Access to the gas inputs, after they have been smashed into one coin. The +gas coin can only be used by reference, except for with +`TransferObjectsTransaction` that can accept it by value. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/gas-cost-summary.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/gas-cost-summary.mdx index 20317c48626..d6859635d3f 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/gas-cost-summary.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/gas-cost-summary.mdx @@ -71,16 +71,17 @@ type GasCostSummary { #### [GasCostSummary.storageRebate](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> Part of storage cost that can be reclaimed by cleaning up data created by this transaction -> (when objects are deleted or an object is modified, which is treated as a deletion followed -> by a creation) (in MICROS). +> Part of storage cost that can be reclaimed by cleaning up data created +> by this transaction (when objects are deleted or an object is +> modified, which is treated as a deletion followed by a creation) (in +> MICROS). > #### [GasCostSummary.nonRefundableStorageFee](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> Part of storage cost that is not reclaimed when data created by this transaction is cleaned -> up (in MICROS). +> Part of storage cost that is not reclaimed when data created by this +> transaction is cleaned up (in MICROS). > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/gas-effects.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/gas-effects.mdx index 2868c0a40d6..46f2398e10c 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/gas-effects.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/gas-effects.mdx @@ -39,7 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Effects related to gas (costs incurred and the identity of the smashed gas object returned). +Effects related to gas (costs incurred and the identity of the smashed gas +object returned). ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/gas-input.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/gas-input.mdx index cf708cdb9c3..c0cd15c82ba 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/gas-input.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/gas-input.mdx @@ -39,7 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Configuration for this transaction's gas price and the coins used to pay for gas. +Configuration for this transaction's gas price and the coins used to pay for +gas. ```graphql @@ -98,14 +99,15 @@ type GasInput { #### [GasInput.gasPrice](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> An unsigned integer specifying the number of native tokens per gas unit this transaction -> will pay (in MICROS). +> An unsigned integer specifying the number of native tokens per gas unit +> this transaction will pay (in MICROS). > #### [GasInput.gasBudget](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> The maximum number of gas units that can be expended by executing this transaction +> The maximum number of gas units that can be expended by executing this +> transaction > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/genesis-transaction.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/genesis-transaction.mdx index 1729a5beda2..586e01f8b57 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/genesis-transaction.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/genesis-transaction.mdx @@ -39,7 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -System transaction that initializes the network and writes the initial set of objects on-chain. +System transaction that initializes the network and writes the initial set +of objects on-chain. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/immutable.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/immutable.mdx index 08556e1fa3f..8b65f27529e 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/immutable.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/immutable.mdx @@ -39,8 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -An immutable object is an object that can't be mutated, transferred, or deleted. -Immutable objects have no owner, so anyone can use them. +An immutable object is an object that can't be mutated, transferred, or +deleted. Immutable objects have no owner, so anyone can use them. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/input.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/input.mdx index 47de73843f5..e2a59169998 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/input.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/input.mdx @@ -39,7 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -One of the input objects or primitive values to the programmable transaction block. +One of the input objects or primitive values to the programmable transaction +block. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/iotans-registration.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/iotans-registration.mdx index 32be266dc39..00f63c02123 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/iotans-registration.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/iotans-registration.mdx @@ -164,8 +164,8 @@ type IotansRegistration implements IMoveObject, IObject, IOwner { #### [IotansRegistration.balance](#)[`Balance`](/references/iota-api/iota-graphql/reference/types/objects/balance) > > -> Total balance of all coins with marker type owned by this object. If type is not supplied, -> it defaults to `0x2::iota::IOTA`. +> Total balance of all coins with marker type owned by this object. If +> type is not supplied, it defaults to `0x2::iota::IOTA`. > ##### [IotansRegistration.balance.type](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > @@ -205,7 +205,8 @@ type IotansRegistration implements IMoveObject, IObject, IOwner { > > The coin objects for this object. > -> `type` is a filter on the coin's type parameter, defaulting to `0x2::iota::IOTA`. +> `type` is a filter on the coin's type parameter, defaulting to +> `0x2::iota::IOTA`. > ##### [IotansRegistration.coins.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -267,7 +268,8 @@ type IotansRegistration implements IMoveObject, IObject, IOwner { #### [IotansRegistration.defaultIotansName](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> The domain explicitly configured as the default domain pointing to this object. +> The domain explicitly configured as the default domain pointing to this +> object. > ##### [IotansRegistration.defaultIotansName.format](#)[`DomainFormat`](/references/iota-api/iota-graphql/reference/types/enums/domain-format) > > @@ -277,8 +279,8 @@ type IotansRegistration implements IMoveObject, IObject, IOwner { #### [IotansRegistration.iotansRegistrations](#)[`IotansRegistrationConnection!`](/references/iota-api/iota-graphql/reference/types/objects/iotans-registration-connection) > > -> The IotansRegistration NFTs owned by this object. These grant the owner the capability to -> manage the associated domain. +> The IotansRegistration NFTs owned by this object. These grant the owner +> the capability to manage the associated domain. > ##### [IotansRegistration.iotansRegistrations.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -312,19 +314,22 @@ type IotansRegistration implements IMoveObject, IObject, IOwner { #### [IotansRegistration.status](#)[`ObjectKind!`](/references/iota-api/iota-graphql/reference/types/enums/object-kind) > > -> The current status of the object as read from the off-chain store. The possible states are: -> NOT_INDEXED, the object is loaded from serialized data, such as the contents of a genesis or -> system package upgrade transaction. LIVE, the version returned is the most recent for the -> object, and it is not deleted or wrapped at that version. HISTORICAL, the object was -> referenced at a specific version or checkpoint, so is fetched from historical tables and may -> not be the latest version of the object. WRAPPED_OR_DELETED, the object is deleted or -> wrapped and only partial information can be loaded." +> The current status of the object as read from the off-chain store. The +> possible states are: NOT_INDEXED, the object is loaded from +> serialized data, such as the contents of a genesis or system package +> upgrade transaction. LIVE, the version returned is the most recent for +> the object, and it is not deleted or wrapped at that version. +> HISTORICAL, the object was referenced at a specific version or +> checkpoint, so is fetched from historical tables and may not be the +> latest version of the object. WRAPPED_OR_DELETED, the object is deleted +> or wrapped and only partial information can be loaded." > #### [IotansRegistration.digest](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> 32-byte hash that identifies the object's contents, encoded as a Base58 string. +> 32-byte hash that identifies the object's contents, encoded as a Base58 +> string. > #### [IotansRegistration.owner](#)[`ObjectOwner`](/references/iota-api/iota-graphql/reference/types/unions/object-owner) @@ -342,8 +347,9 @@ type IotansRegistration implements IMoveObject, IObject, IOwner { #### [IotansRegistration.storageRebate](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> The amount of IOTA we would rebate if this object gets deleted or mutated. This number is -> recalculated based on the present storage gas price. +> The amount of IOTA we would rebate if this object gets deleted or +> mutated. This number is recalculated based on the present storage +> gas price. > #### [IotansRegistration.receivedTransactionBlocks](#)[`TransactionBlockConnection!`](/references/iota-api/iota-graphql/reference/types/objects/transaction-block-connection) @@ -389,36 +395,37 @@ type IotansRegistration implements IMoveObject, IObject, IOwner { #### [IotansRegistration.contents](#)[`MoveValue`](/references/iota-api/iota-graphql/reference/types/objects/move-value) > > -> Displays the contents of the Move object in a JSON string and through GraphQL types. Also -> provides the flat representation of the type signature, and the BCS of the corresponding -> data. +> Displays the contents of the Move object in a JSON string and through +> GraphQL types. Also provides the flat representation of the type +> signature, and the BCS of the corresponding data. > #### [IotansRegistration.hasPublicTransfer](#)[`Boolean!`](/references/iota-api/iota-graphql/reference/types/scalars/boolean) > > -> Determines whether a transaction can transfer this object, using the TransferObjects -> transaction command or `iota::transfer::public_transfer`, both of which require the object to +> Determines whether a transaction can transfer this object, using the +> TransferObjects transaction command or +> `iota::transfer::public_transfer`, both of which require the object to > have the `key` and `store` abilities. > #### [IotansRegistration.display](#)[`[DisplayEntry!]`](/references/iota-api/iota-graphql/reference/types/objects/display-entry) > > -> The set of named templates defined on-chain for the type of this object, to be handled -> off-chain. The server substitutes data from the object into these templates to generate a -> display string per template. +> The set of named templates defined on-chain for the type of this object, +> to be handled off-chain. The server substitutes data from the object +> into these templates to generate a display string per template. > #### [IotansRegistration.dynamicField](#)[`DynamicField`](/references/iota-api/iota-graphql/reference/types/objects/dynamic-field) > > -> Access a dynamic field on an object using its name. Names are arbitrary Move values whose -> type have `copy`, `drop`, and `store`, and are specified using their type, and their BCS -> contents, Base64 encoded. +> Access a dynamic field on an object using its name. Names are arbitrary +> Move values whose type have `copy`, `drop`, and `store`, and are +> specified using their type, and their BCS contents, Base64 encoded. > -> Dynamic fields on wrapped objects can be accessed by using the same API under the Owner -> type. +> Dynamic fields on wrapped objects can be accessed by using the same API +> under the Owner type. > ##### [IotansRegistration.dynamicField.name](#)[`DynamicFieldName!`](/references/iota-api/iota-graphql/reference/types/inputs/dynamic-field-name) > > @@ -428,13 +435,14 @@ type IotansRegistration implements IMoveObject, IObject, IOwner { #### [IotansRegistration.dynamicObjectField](#)[`DynamicField`](/references/iota-api/iota-graphql/reference/types/objects/dynamic-field) > > -> Access a dynamic object field on an object using its name. Names are arbitrary Move values -> whose type have `copy`, `drop`, and `store`, and are specified using their type, and their -> BCS contents, Base64 encoded. The value of a dynamic object field can also be accessed +> Access a dynamic object field on an object using its name. Names are +> arbitrary Move values whose type have `copy`, `drop`, and `store`, +> and are specified using their type, and their BCS contents, Base64 +> encoded. The value of a dynamic object field can also be accessed > off-chain directly via its address (e.g. using `Query.object`). > -> Dynamic fields on wrapped objects can be accessed by using the same API under the Owner -> type. +> Dynamic fields on wrapped objects can be accessed by using the same API +> under the Owner type. > ##### [IotansRegistration.dynamicObjectField.name](#)[`DynamicFieldName!`](/references/iota-api/iota-graphql/reference/types/inputs/dynamic-field-name) > > @@ -446,8 +454,8 @@ type IotansRegistration implements IMoveObject, IObject, IOwner { > > The dynamic fields and dynamic object fields on an object. > -> Dynamic fields on wrapped objects can be accessed by using the same API under the Owner -> type. +> Dynamic fields on wrapped objects can be accessed by using the same API +> under the Owner type. > ##### [IotansRegistration.dynamicFields.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -483,24 +491,25 @@ type IotansRegistration implements IMoveObject, IObject, IOwner { #### [`IMoveObject`](/references/iota-api/iota-graphql/reference/types/interfaces/imove-object) > > -> This interface is implemented by types that represent a Move object on-chain (A Move value whose -> type has `key`). +> This interface is implemented by types that represent a Move object on-chain +> (A Move value whose type has `key`). > #### [`IObject`](/references/iota-api/iota-graphql/reference/types/interfaces/iobject) > > -> Interface implemented by on-chain values that are addressable by an ID (also referred to as its -> address). This includes Move objects and packages. +> Interface implemented by on-chain values that are addressable by an ID (also +> referred to as its address). This includes Move objects and packages. > #### [`IOwner`](/references/iota-api/iota-graphql/reference/types/interfaces/iowner) > > -> Interface implemented by GraphQL types representing entities that can own objects. Object owners -> are identified by an address which can represent either the public key of an account or another -> object. The same address can only refer to an account or an object, never both, but it is not -> possible to know which up-front. +> Interface implemented by GraphQL types representing entities that can own +> objects. Object owners are identified by an address which can represent +> either the public key of an account or another object. The same address can +> only refer to an account or an object, never both, but it is not possible to +> know which up-front. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/linkage.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/linkage.mdx index c5d968363b5..f0568508050 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/linkage.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/linkage.mdx @@ -39,7 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Information used by a package to link to a specific version of its dependency. +Information used by a package to link to a specific version of its +dependency. ```graphql @@ -64,7 +65,8 @@ type Linkage { #### [Linkage.upgradedId](#)[`IotaAddress!`](/references/iota-api/iota-graphql/reference/types/scalars/iota-address) > > -> The ID on-chain of the version of the dependency that this package depends on. +> The ID on-chain of the version of the dependency that this package +> depends on. > #### [Linkage.version](#)[`Int!`](/references/iota-api/iota-graphql/reference/types/scalars/int) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/make-move-vec-transaction.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/make-move-vec-transaction.mdx index d249a665db7..0bd7afea8e1 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/make-move-vec-transaction.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/make-move-vec-transaction.mdx @@ -57,7 +57,8 @@ type MakeMoveVecTransaction { #### [MakeMoveVecTransaction.type](#)[`MoveType`](/references/iota-api/iota-graphql/reference/types/objects/move-type) > > -> If the elements are not objects, or the vector is empty, a type must be supplied. +> If the elements are not objects, or the vector is empty, a type must be +> supplied. > #### [MakeMoveVecTransaction.elements](#)[`[TransactionArgument!]!`](/references/iota-api/iota-graphql/reference/types/unions/transaction-argument) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-function.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-function.mdx index d91c0de46e6..db50baae0d0 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-function.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-function.mdx @@ -86,24 +86,25 @@ type MoveFunction { #### [MoveFunction.typeParameters](#)[`[MoveFunctionTypeParameter!]`](/references/iota-api/iota-graphql/reference/types/objects/move-function-type-parameter) > > -> Constraints on the function's formal type parameters. Move bytecode does not name type -> parameters, so when they are referenced (e.g. in parameter and return types) they are -> identified by their index in this list. +> Constraints on the function's formal type parameters. Move bytecode +> does not name type parameters, so when they are referenced (e.g. in +> parameter and return types) they are identified by their index in +> this list. > #### [MoveFunction.parameters](#)[`[OpenMoveType!]`](/references/iota-api/iota-graphql/reference/types/objects/open-move-type) > > -> The function's parameter types. These types can reference type parameters introduce by this -> function (see `typeParameters`). +> The function's parameter types. These types can reference type +> parameters introduce by this function (see `typeParameters`). > #### [MoveFunction.return](#)[`[OpenMoveType!]`](/references/iota-api/iota-graphql/reference/types/objects/open-move-type) > > -> The function's return types. There can be multiple because functions in Move can return -> multiple values. These types can reference type parameters introduced by this function (see -> `typeParameters`). +> The function's return types. There can be multiple because functions in +> Move can return multiple values. These types can reference type +> parameters introduced by this function (see `typeParameters`). > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-module.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-module.mdx index f468d683026..987c4e86ac8 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-module.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-module.mdx @@ -103,8 +103,8 @@ type MoveModule { #### [MoveModule.friends](#)[`MoveModuleConnection!`](/references/iota-api/iota-graphql/reference/types/objects/move-module-connection) > > -> Modules that this module considers friends (these modules can access `public(friend)` -> functions from this module). +> Modules that this module considers friends (these modules can access +> `public(friend)` functions from this module). > ##### [MoveModule.friends.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-object.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-object.mdx index a18bfdb3071..49a8cbef122 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-object.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-object.mdx @@ -39,8 +39,9 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -The representation of an object as a Move Object, which exposes additional information -(content, module that governs it, version, is transferrable, etc.) about this object. +The representation of an object as a Move Object, which exposes additional +information (content, module that governs it, version, is transferrable, +etc.) about this object. ```graphql @@ -168,8 +169,8 @@ type MoveObject implements IMoveObject, IObject, IOwner { #### [MoveObject.balance](#)[`Balance`](/references/iota-api/iota-graphql/reference/types/objects/balance) > > -> Total balance of all coins with marker type owned by this object. If type is not supplied, -> it defaults to `0x2::iota::IOTA`. +> Total balance of all coins with marker type owned by this object. If +> type is not supplied, it defaults to `0x2::iota::IOTA`. > ##### [MoveObject.balance.type](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > @@ -209,7 +210,8 @@ type MoveObject implements IMoveObject, IObject, IOwner { > > The coin objects for this object. > -> `type` is a filter on the coin's type parameter, defaulting to `0x2::iota::IOTA`. +> `type` is a filter on the coin's type parameter, defaulting to +> `0x2::iota::IOTA`. > ##### [MoveObject.coins.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -271,7 +273,8 @@ type MoveObject implements IMoveObject, IObject, IOwner { #### [MoveObject.defaultIotansName](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> The domain explicitly configured as the default domain pointing to this object. +> The domain explicitly configured as the default domain pointing to this +> object. > ##### [MoveObject.defaultIotansName.format](#)[`DomainFormat`](/references/iota-api/iota-graphql/reference/types/enums/domain-format) > > @@ -281,8 +284,8 @@ type MoveObject implements IMoveObject, IObject, IOwner { #### [MoveObject.iotansRegistrations](#)[`IotansRegistrationConnection!`](/references/iota-api/iota-graphql/reference/types/objects/iotans-registration-connection) > > -> The IotansRegistration NFTs owned by this object. These grant the owner the capability to -> manage the associated domain. +> The IotansRegistration NFTs owned by this object. These grant the owner +> the capability to manage the associated domain. > ##### [MoveObject.iotansRegistrations.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -316,19 +319,22 @@ type MoveObject implements IMoveObject, IObject, IOwner { #### [MoveObject.status](#)[`ObjectKind!`](/references/iota-api/iota-graphql/reference/types/enums/object-kind) > > -> The current status of the object as read from the off-chain store. The possible states are: -> NOT_INDEXED, the object is loaded from serialized data, such as the contents of a genesis or -> system package upgrade transaction. LIVE, the version returned is the most recent for the -> object, and it is not deleted or wrapped at that version. HISTORICAL, the object was -> referenced at a specific version or checkpoint, so is fetched from historical tables and may -> not be the latest version of the object. WRAPPED_OR_DELETED, the object is deleted or -> wrapped and only partial information can be loaded." +> The current status of the object as read from the off-chain store. The +> possible states are: NOT_INDEXED, the object is loaded from +> serialized data, such as the contents of a genesis or system package +> upgrade transaction. LIVE, the version returned is the most recent for +> the object, and it is not deleted or wrapped at that version. +> HISTORICAL, the object was referenced at a specific version or +> checkpoint, so is fetched from historical tables and may not be the +> latest version of the object. WRAPPED_OR_DELETED, the object is deleted +> or wrapped and only partial information can be loaded." > #### [MoveObject.digest](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> 32-byte hash that identifies the object's contents, encoded as a Base58 string. +> 32-byte hash that identifies the object's contents, encoded as a Base58 +> string. > #### [MoveObject.owner](#)[`ObjectOwner`](/references/iota-api/iota-graphql/reference/types/unions/object-owner) @@ -346,8 +352,9 @@ type MoveObject implements IMoveObject, IObject, IOwner { #### [MoveObject.storageRebate](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> The amount of IOTA we would rebate if this object gets deleted or mutated. This number is -> recalculated based on the present storage gas price. +> The amount of IOTA we would rebate if this object gets deleted or +> mutated. This number is recalculated based on the present storage +> gas price. > #### [MoveObject.receivedTransactionBlocks](#)[`TransactionBlockConnection!`](/references/iota-api/iota-graphql/reference/types/objects/transaction-block-connection) @@ -393,36 +400,37 @@ type MoveObject implements IMoveObject, IObject, IOwner { #### [MoveObject.contents](#)[`MoveValue`](/references/iota-api/iota-graphql/reference/types/objects/move-value) > > -> Displays the contents of the Move object in a JSON string and through GraphQL types. Also -> provides the flat representation of the type signature, and the BCS of the corresponding -> data. +> Displays the contents of the Move object in a JSON string and through +> GraphQL types. Also provides the flat representation of the type +> signature, and the BCS of the corresponding data. > #### [MoveObject.hasPublicTransfer](#)[`Boolean!`](/references/iota-api/iota-graphql/reference/types/scalars/boolean) > > -> Determines whether a transaction can transfer this object, using the TransferObjects -> transaction command or `iota::transfer::public_transfer`, both of which require the object to +> Determines whether a transaction can transfer this object, using the +> TransferObjects transaction command or +> `iota::transfer::public_transfer`, both of which require the object to > have the `key` and `store` abilities. > #### [MoveObject.display](#)[`[DisplayEntry!]`](/references/iota-api/iota-graphql/reference/types/objects/display-entry) > > -> The set of named templates defined on-chain for the type of this object, to be handled -> off-chain. The server substitutes data from the object into these templates to generate a -> display string per template. +> The set of named templates defined on-chain for the type of this object, +> to be handled off-chain. The server substitutes data from the object +> into these templates to generate a display string per template. > #### [MoveObject.dynamicField](#)[`DynamicField`](/references/iota-api/iota-graphql/reference/types/objects/dynamic-field) > > -> Access a dynamic field on an object using its name. Names are arbitrary Move values whose -> type have `copy`, `drop`, and `store`, and are specified using their type, and their BCS -> contents, Base64 encoded. +> Access a dynamic field on an object using its name. Names are arbitrary +> Move values whose type have `copy`, `drop`, and `store`, and are +> specified using their type, and their BCS contents, Base64 encoded. > -> Dynamic fields on wrapped objects can be accessed by using the same API under the Owner -> type. +> Dynamic fields on wrapped objects can be accessed by using the same API +> under the Owner type. > ##### [MoveObject.dynamicField.name](#)[`DynamicFieldName!`](/references/iota-api/iota-graphql/reference/types/inputs/dynamic-field-name) > > @@ -432,13 +440,14 @@ type MoveObject implements IMoveObject, IObject, IOwner { #### [MoveObject.dynamicObjectField](#)[`DynamicField`](/references/iota-api/iota-graphql/reference/types/objects/dynamic-field) > > -> Access a dynamic object field on an object using its name. Names are arbitrary Move values -> whose type have `copy`, `drop`, and `store`, and are specified using their type, and their -> BCS contents, Base64 encoded. The value of a dynamic object field can also be accessed +> Access a dynamic object field on an object using its name. Names are +> arbitrary Move values whose type have `copy`, `drop`, and `store`, +> and are specified using their type, and their BCS contents, Base64 +> encoded. The value of a dynamic object field can also be accessed > off-chain directly via its address (e.g. using `Query.object`). > -> Dynamic fields on wrapped objects can be accessed by using the same API under the Owner -> type. +> Dynamic fields on wrapped objects can be accessed by using the same API +> under the Owner type. > ##### [MoveObject.dynamicObjectField.name](#)[`DynamicFieldName!`](/references/iota-api/iota-graphql/reference/types/inputs/dynamic-field-name) > > @@ -450,8 +459,8 @@ type MoveObject implements IMoveObject, IObject, IOwner { > > The dynamic fields and dynamic object fields on an object. > -> Dynamic fields on wrapped objects can be accessed by using the same API under the Owner -> type. +> Dynamic fields on wrapped objects can be accessed by using the same API +> under the Owner type. > ##### [MoveObject.dynamicFields.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -485,7 +494,8 @@ type MoveObject implements IMoveObject, IObject, IOwner { #### [MoveObject.asStakedIota](#)[`StakedIota`](/references/iota-api/iota-graphql/reference/types/objects/staked-iota) > > -> Attempts to convert the Move object into a `0x3::staking_pool::StakedIota`. +> Attempts to convert the Move object into a +> `0x3::staking_pool::StakedIota`. > #### [MoveObject.asCoinMetadata](#)[`CoinMetadata`](/references/iota-api/iota-graphql/reference/types/objects/coin-metadata) @@ -505,24 +515,25 @@ type MoveObject implements IMoveObject, IObject, IOwner { #### [`IMoveObject`](/references/iota-api/iota-graphql/reference/types/interfaces/imove-object) > > -> This interface is implemented by types that represent a Move object on-chain (A Move value whose -> type has `key`). +> This interface is implemented by types that represent a Move object on-chain +> (A Move value whose type has `key`). > #### [`IObject`](/references/iota-api/iota-graphql/reference/types/interfaces/iobject) > > -> Interface implemented by on-chain values that are addressable by an ID (also referred to as its -> address). This includes Move objects and packages. +> Interface implemented by on-chain values that are addressable by an ID (also +> referred to as its address). This includes Move objects and packages. > #### [`IOwner`](/references/iota-api/iota-graphql/reference/types/interfaces/iowner) > > -> Interface implemented by GraphQL types representing entities that can own objects. Object owners -> are identified by an address which can represent either the public key of an account or another -> object. The same address can only refer to an account or an object, never both, but it is not -> possible to know which up-front. +> Interface implemented by GraphQL types representing entities that can own +> objects. Object owners are identified by an address which can represent +> either the public key of an account or another object. The same address can +> only refer to an account or an object, never both, but it is not possible to +> know which up-front. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-package.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-package.mdx index b1186c86fc9..0a82668ab04 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-package.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-package.mdx @@ -39,8 +39,9 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -A MovePackage is a kind of Move object that represents code that has been published on chain. -It exposes information about its modules, type definitions, functions, and dependencies. +A MovePackage is a kind of Move object that represents code that has been +published on chain. It exposes information about its modules, type +definitions, functions, and dependencies. ```graphql @@ -129,8 +130,8 @@ type MovePackage implements IObject, IOwner { > > Objects owned by this package, optionally `filter`-ed. > -> Note that objects owned by a package are inaccessible, because packages are immutable and -> cannot be owned by an address. +> Note that objects owned by a package are inaccessible, because packages +> are immutable and cannot be owned by an address. > ##### [MovePackage.objects.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -164,11 +165,11 @@ type MovePackage implements IObject, IOwner { #### [MovePackage.balance](#)[`Balance`](/references/iota-api/iota-graphql/reference/types/objects/balance) > > -> Total balance of all coins with marker type owned by this package. If type is not supplied, -> it defaults to `0x2::iota::IOTA`. +> Total balance of all coins with marker type owned by this package. If +> type is not supplied, it defaults to `0x2::iota::IOTA`. > -> Note that coins owned by a package are inaccessible, because packages are immutable and -> cannot be owned by an address. +> Note that coins owned by a package are inaccessible, because packages +> are immutable and cannot be owned by an address. > ##### [MovePackage.balance.type](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > @@ -180,8 +181,8 @@ type MovePackage implements IObject, IOwner { > > The balances of all coin types owned by this package. > -> Note that coins owned by a package are inaccessible, because packages are immutable and -> cannot be owned by an address. +> Note that coins owned by a package are inaccessible, because packages +> are immutable and cannot be owned by an address. > ##### [MovePackage.balances.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -211,10 +212,11 @@ type MovePackage implements IObject, IOwner { > > The coin objects owned by this package. > -> `type` is a filter on the coin's type parameter, defaulting to `0x2::iota::IOTA`. +> `type` is a filter on the coin's type parameter, defaulting to +> `0x2::iota::IOTA`. > -> Note that coins owned by a package are inaccessible, because packages are immutable and -> cannot be owned by an address. +> Note that coins owned by a package are inaccessible, because packages +> are immutable and cannot be owned by an address. > ##### [MovePackage.coins.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -250,8 +252,8 @@ type MovePackage implements IObject, IOwner { > > The `0x3::staking_pool::StakedIota` objects owned by this package. > -> Note that objects owned by a package are inaccessible, because packages are immutable and -> cannot be owned by an address. +> Note that objects owned by a package are inaccessible, because packages +> are immutable and cannot be owned by an address. > ##### [MovePackage.stakedIotas.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -279,7 +281,8 @@ type MovePackage implements IObject, IOwner { #### [MovePackage.defaultIotansName](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> The domain explicitly configured as the default domain pointing to this object. +> The domain explicitly configured as the default domain pointing to this +> object. > ##### [MovePackage.defaultIotansName.format](#)[`DomainFormat`](/references/iota-api/iota-graphql/reference/types/enums/domain-format) > > @@ -289,11 +292,11 @@ type MovePackage implements IObject, IOwner { #### [MovePackage.iotansRegistrations](#)[`IotansRegistrationConnection!`](/references/iota-api/iota-graphql/reference/types/objects/iotans-registration-connection) > > -> The IotansRegistration NFTs owned by this package. These grant the owner the capability to -> manage the associated domain. +> The IotansRegistration NFTs owned by this package. These grant the owner +> the capability to manage the associated domain. > -> Note that objects owned by a package are inaccessible, because packages are immutable and -> cannot be owned by an address. +> Note that objects owned by a package are inaccessible, because packages +> are immutable and cannot be owned by an address. > ##### [MovePackage.iotansRegistrations.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -327,19 +330,22 @@ type MovePackage implements IObject, IOwner { #### [MovePackage.status](#)[`ObjectKind!`](/references/iota-api/iota-graphql/reference/types/enums/object-kind) > > -> The current status of the object as read from the off-chain store. The possible states are: -> NOT_INDEXED, the object is loaded from serialized data, such as the contents of a genesis or -> system package upgrade transaction. LIVE, the version returned is the most recent for the -> object, and it is not deleted or wrapped at that version. HISTORICAL, the object was -> referenced at a specific version or checkpoint, so is fetched from historical tables and may -> not be the latest version of the object. WRAPPED_OR_DELETED, the object is deleted or -> wrapped and only partial information can be loaded." +> The current status of the object as read from the off-chain store. The +> possible states are: NOT_INDEXED, the object is loaded from +> serialized data, such as the contents of a genesis or system package +> upgrade transaction. LIVE, the version returned is the most recent for +> the object, and it is not deleted or wrapped at that version. +> HISTORICAL, the object was referenced at a specific version or +> checkpoint, so is fetched from historical tables and may not be the +> latest version of the object. WRAPPED_OR_DELETED, the object is deleted +> or wrapped and only partial information can be loaded." > #### [MovePackage.digest](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> 32-byte hash that identifies the package's contents, encoded as a Base58 string. +> 32-byte hash that identifies the package's contents, encoded as a Base58 +> string. > #### [MovePackage.owner](#)[`ObjectOwner`](/references/iota-api/iota-graphql/reference/types/unions/object-owner) @@ -358,11 +364,12 @@ type MovePackage implements IObject, IOwner { #### [MovePackage.storageRebate](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> The amount of IOTA we would rebate if this object gets deleted or mutated. This number is -> recalculated based on the present storage gas price. +> The amount of IOTA we would rebate if this object gets deleted or +> mutated. This number is recalculated based on the present storage +> gas price. > -> Note that packages cannot be deleted or mutated, so this number is provided purely for -> reference. +> Note that packages cannot be deleted or mutated, so this number is +> provided purely for reference. > #### [MovePackage.receivedTransactionBlocks](#)[`TransactionBlockConnection!`](/references/iota-api/iota-graphql/reference/types/objects/transaction-block-connection) @@ -410,8 +417,8 @@ type MovePackage implements IObject, IOwner { #### [MovePackage.module](#)[`MoveModule`](/references/iota-api/iota-graphql/reference/types/objects/move-module) > > -> A representation of the module called `name` in this package, including the -> structs and functions it defines. +> A representation of the module called `name` in this package, including +> the structs and functions it defines. > ##### [MovePackage.module.name](#)[`String!`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > @@ -461,8 +468,9 @@ type MovePackage implements IObject, IOwner { #### [MovePackage.moduleBcs](#)[`Base64`](/references/iota-api/iota-graphql/reference/types/scalars/base-64) > > -> BCS representation of the package's modules. Modules appear as a sequence of pairs (module -> name, followed by module bytes), in alphabetic order by module name. +> BCS representation of the package's modules. Modules appear as a +> sequence of pairs (module name, followed by module bytes), in +> alphabetic order by module name. > ### Interfaces @@ -470,17 +478,18 @@ type MovePackage implements IObject, IOwner { #### [`IObject`](/references/iota-api/iota-graphql/reference/types/interfaces/iobject) > > -> Interface implemented by on-chain values that are addressable by an ID (also referred to as its -> address). This includes Move objects and packages. +> Interface implemented by on-chain values that are addressable by an ID (also +> referred to as its address). This includes Move objects and packages. > #### [`IOwner`](/references/iota-api/iota-graphql/reference/types/interfaces/iowner) > > -> Interface implemented by GraphQL types representing entities that can own objects. Object owners -> are identified by an address which can represent either the public key of an account or another -> object. The same address can only refer to an account or an object, never both, but it is not -> possible to know which up-front. +> Interface implemented by GraphQL types representing entities that can own +> objects. Object owners are identified by an address which can represent +> either the public key of an account or another object. The same address can +> only refer to an account or an object, never both, but it is not possible to +> know which up-front. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-struct.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-struct.mdx index c5ef67c5de0..664316f5f21 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-struct.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-struct.mdx @@ -78,16 +78,17 @@ type MoveStruct { #### [MoveStruct.typeParameters](#)[`[MoveStructTypeParameter!]`](/references/iota-api/iota-graphql/reference/types/objects/move-struct-type-parameter) > > -> Constraints on the struct's formal type parameters. Move bytecode does not name type -> parameters, so when they are referenced (e.g. in field types) they are identified by their -> index in this list. +> Constraints on the struct's formal type parameters. Move bytecode does +> not name type parameters, so when they are referenced (e.g. in field +> types) they are identified by their index in this list. > #### [MoveStruct.fields](#)[`[MoveField!]`](/references/iota-api/iota-graphql/reference/types/objects/move-field) > > -> The names and types of the struct's fields. Field types reference type parameters, by their -> index in the defining struct's `typeParameters` list. +> The names and types of the struct's fields. Field types reference type +> parameters, by their index in the defining struct's `typeParameters` +> list. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-value.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-value.mdx index 08db5277cb1..b6ea886d03b 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-value.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/move-value.mdx @@ -79,7 +79,8 @@ type MoveValue { > > Representation of a Move value in JSON, where: > -> - Addresses, IDs, and UIDs are represented in canonical form, as JSON strings. +> - Addresses, IDs, and UIDs are represented in canonical form, as JSON +> strings. > - Bools are represented by JSON boolean literals. > - u8, u16, and u32 are represented as JSON numbers. > - u64, u128, and u256 are represented as JSON strings. @@ -87,8 +88,8 @@ type MoveValue { > - Structs are represented by JSON objects. > - Empty optional values are represented by `null`. > -> This form is offered as a less verbose convenience in cases where the layout of the type is -> known by the client. +> This form is offered as a less verbose convenience in cases where the +> layout of the type is known by the client. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/object.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/object.mdx index 3b7f3255eb0..976fec00e74 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/object.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/object.mdx @@ -39,9 +39,10 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -An object in Iota is a package (set of Move bytecode modules) or object (typed data structure -with fields) with additional metadata detailing its id, version, transaction digest, owner -field indicating how this object can be accessed. +An object in Iota is a package (set of Move bytecode modules) or object +(typed data structure with fields) with additional metadata detailing its +id, version, transaction digest, owner field indicating how this object can +be accessed. ```graphql @@ -165,8 +166,8 @@ type Object implements IObject, IOwner { #### [Object.balance](#)[`Balance`](/references/iota-api/iota-graphql/reference/types/objects/balance) > > -> Total balance of all coins with marker type owned by this object. If type is not supplied, -> it defaults to `0x2::iota::IOTA`. +> Total balance of all coins with marker type owned by this object. If +> type is not supplied, it defaults to `0x2::iota::IOTA`. > ##### [Object.balance.type](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > @@ -206,7 +207,8 @@ type Object implements IObject, IOwner { > > The coin objects for this object. > -> `type` is a filter on the coin's type parameter, defaulting to `0x2::iota::IOTA`. +> `type` is a filter on the coin's type parameter, defaulting to +> `0x2::iota::IOTA`. > ##### [Object.coins.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -268,7 +270,8 @@ type Object implements IObject, IOwner { #### [Object.defaultIotansName](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> The domain explicitly configured as the default domain pointing to this object. +> The domain explicitly configured as the default domain pointing to this +> object. > ##### [Object.defaultIotansName.format](#)[`DomainFormat`](/references/iota-api/iota-graphql/reference/types/enums/domain-format) > > @@ -278,8 +281,8 @@ type Object implements IObject, IOwner { #### [Object.iotansRegistrations](#)[`IotansRegistrationConnection!`](/references/iota-api/iota-graphql/reference/types/objects/iotans-registration-connection) > > -> The IotansRegistration NFTs owned by this object. These grant the owner the capability to -> manage the associated domain. +> The IotansRegistration NFTs owned by this object. These grant the owner +> the capability to manage the associated domain. > ##### [Object.iotansRegistrations.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -313,19 +316,22 @@ type Object implements IObject, IOwner { #### [Object.status](#)[`ObjectKind!`](/references/iota-api/iota-graphql/reference/types/enums/object-kind) > > -> The current status of the object as read from the off-chain store. The possible states are: -> NOT_INDEXED, the object is loaded from serialized data, such as the contents of a genesis or -> system package upgrade transaction. LIVE, the version returned is the most recent for the -> object, and it is not deleted or wrapped at that version. HISTORICAL, the object was -> referenced at a specific version or checkpoint, so is fetched from historical tables and may -> not be the latest version of the object. WRAPPED_OR_DELETED, the object is deleted or -> wrapped and only partial information can be loaded." +> The current status of the object as read from the off-chain store. The +> possible states are: NOT_INDEXED, the object is loaded from +> serialized data, such as the contents of a genesis or system package +> upgrade transaction. LIVE, the version returned is the most recent for +> the object, and it is not deleted or wrapped at that version. +> HISTORICAL, the object was referenced at a specific version or +> checkpoint, so is fetched from historical tables and may not be the +> latest version of the object. WRAPPED_OR_DELETED, the object is deleted +> or wrapped and only partial information can be loaded." > #### [Object.digest](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> 32-byte hash that identifies the object's current contents, encoded as a Base58 string. +> 32-byte hash that identifies the object's current contents, encoded as a +> Base58 string. > #### [Object.owner](#)[`ObjectOwner`](/references/iota-api/iota-graphql/reference/types/unions/object-owner) @@ -344,8 +350,9 @@ type Object implements IObject, IOwner { #### [Object.storageRebate](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> The amount of IOTA we would rebate if this object gets deleted or mutated. This number is -> recalculated based on the present storage gas price. +> The amount of IOTA we would rebate if this object gets deleted or +> mutated. This number is recalculated based on the present storage +> gas price. > #### [Object.receivedTransactionBlocks](#)[`TransactionBlockConnection!`](/references/iota-api/iota-graphql/reference/types/objects/transaction-block-connection) @@ -391,20 +398,20 @@ type Object implements IObject, IOwner { #### [Object.display](#)[`[DisplayEntry!]`](/references/iota-api/iota-graphql/reference/types/objects/display-entry) > > -> The set of named templates defined on-chain for the type of this object, to be handled -> off-chain. The server substitutes data from the object into these templates to generate a -> display string per template. +> The set of named templates defined on-chain for the type of this object, +> to be handled off-chain. The server substitutes data from the object +> into these templates to generate a display string per template. > #### [Object.dynamicField](#)[`DynamicField`](/references/iota-api/iota-graphql/reference/types/objects/dynamic-field) > > -> Access a dynamic field on an object using its name. Names are arbitrary Move values whose -> type have `copy`, `drop`, and `store`, and are specified using their type, and their BCS -> contents, Base64 encoded. +> Access a dynamic field on an object using its name. Names are arbitrary +> Move values whose type have `copy`, `drop`, and `store`, and are +> specified using their type, and their BCS contents, Base64 encoded. > -> Dynamic fields on wrapped objects can be accessed by using the same API under the Owner -> type. +> Dynamic fields on wrapped objects can be accessed by using the same API +> under the Owner type. > ##### [Object.dynamicField.name](#)[`DynamicFieldName!`](/references/iota-api/iota-graphql/reference/types/inputs/dynamic-field-name) > > @@ -414,13 +421,14 @@ type Object implements IObject, IOwner { #### [Object.dynamicObjectField](#)[`DynamicField`](/references/iota-api/iota-graphql/reference/types/objects/dynamic-field) > > -> Access a dynamic object field on an object using its name. Names are arbitrary Move values -> whose type have `copy`, `drop`, and `store`, and are specified using their type, and their -> BCS contents, Base64 encoded. The value of a dynamic object field can also be accessed +> Access a dynamic object field on an object using its name. Names are +> arbitrary Move values whose type have `copy`, `drop`, and `store`, +> and are specified using their type, and their BCS contents, Base64 +> encoded. The value of a dynamic object field can also be accessed > off-chain directly via its address (e.g. using `Query.object`). > -> Dynamic fields on wrapped objects can be accessed by using the same API under the Owner -> type. +> Dynamic fields on wrapped objects can be accessed by using the same API +> under the Owner type. > ##### [Object.dynamicObjectField.name](#)[`DynamicFieldName!`](/references/iota-api/iota-graphql/reference/types/inputs/dynamic-field-name) > > @@ -432,8 +440,8 @@ type Object implements IObject, IOwner { > > The dynamic fields and dynamic object fields on an object. > -> Dynamic fields on wrapped objects can be accessed by using the same API under the Owner -> type. +> Dynamic fields on wrapped objects can be accessed by using the same API +> under the Owner type. > ##### [Object.dynamicFields.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -475,17 +483,18 @@ type Object implements IObject, IOwner { #### [`IObject`](/references/iota-api/iota-graphql/reference/types/interfaces/iobject) > > -> Interface implemented by on-chain values that are addressable by an ID (also referred to as its -> address). This includes Move objects and packages. +> Interface implemented by on-chain values that are addressable by an ID (also +> referred to as its address). This includes Move objects and packages. > #### [`IOwner`](/references/iota-api/iota-graphql/reference/types/interfaces/iowner) > > -> Interface implemented by GraphQL types representing entities that can own objects. Object owners -> are identified by an address which can represent either the public key of an account or another -> object. The same address can only refer to an account or an object, never both, but it is not -> possible to know which up-front. +> Interface implemented by GraphQL types representing entities that can own +> objects. Object owners are identified by an address which can represent +> either the public key of an account or another object. The same address can +> only refer to an account or an object, never both, but it is not possible to +> know which up-front. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/open-move-type.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/open-move-type.mdx index f6d5c806a96..7a16f9fe681 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/open-move-type.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/open-move-type.mdx @@ -39,8 +39,9 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Represents types that could contain references or free type parameters. Such types can appear -as function parameters, in fields of structs, or as actual type parameter. +Represents types that could contain references or free type parameters. +Such types can appear as function parameters, in fields of structs, or as +actual type parameter. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/owned-or-immutable.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/owned-or-immutable.mdx index 91b4aa6e793..ef71ecd76e5 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/owned-or-immutable.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/owned-or-immutable.mdx @@ -71,8 +71,8 @@ type OwnedOrImmutable { #### [OwnedOrImmutable.digest](#)[`String!`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> 32-byte hash that identifies the object's contents at this version, encoded as a Base58 -> string. +> 32-byte hash that identifies the object's contents at this version, +> encoded as a Base58 string. > #### [OwnedOrImmutable.object](#)[`Object`](/references/iota-api/iota-graphql/reference/types/objects/object) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/owner.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/owner.mdx index 4024f0890ef..2af2f43df77 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/owner.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/owner.mdx @@ -39,9 +39,10 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -An Owner is an entity that can own an object. Each Owner is identified by a IotaAddress which -represents either an Address (corresponding to a public key of an account) or an Object, but -never both (it is not known up-front whether a given Owner is an Address or an Object). +An Owner is an entity that can own an object. Each Owner is identified by a +IotaAddress which represents either an Address (corresponding to a public +key of an account) or an Object, but never both (it is not known up-front +whether a given Owner is an Address or an Object). ```graphql @@ -150,8 +151,8 @@ type Owner implements IOwner { #### [Owner.balance](#)[`Balance`](/references/iota-api/iota-graphql/reference/types/objects/balance) > > -> Total balance of all coins with marker type owned by this object or address. If type is not -> supplied, it defaults to `0x2::iota::IOTA`. +> Total balance of all coins with marker type owned by this object or +> address. If type is not supplied, it defaults to `0x2::iota::IOTA`. > ##### [Owner.balance.type](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > @@ -191,7 +192,8 @@ type Owner implements IOwner { > > The coin objects for this object or address. > -> `type` is a filter on the coin's type parameter, defaulting to `0x2::iota::IOTA`. +> `type` is a filter on the coin's type parameter, defaulting to +> `0x2::iota::IOTA`. > ##### [Owner.coins.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -225,7 +227,8 @@ type Owner implements IOwner { #### [Owner.stakedIotas](#)[`StakedIotaConnection!`](/references/iota-api/iota-graphql/reference/types/objects/staked-iota-connection) > > -> The `0x3::staking_pool::StakedIota` objects owned by this object or address. +> The `0x3::staking_pool::StakedIota` objects owned by this object or +> address. > ##### [Owner.stakedIotas.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -253,7 +256,8 @@ type Owner implements IOwner { #### [Owner.defaultIotansName](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> The domain explicitly configured as the default domain pointing to this object or address. +> The domain explicitly configured as the default domain pointing to this +> object or address. > ##### [Owner.defaultIotansName.format](#)[`DomainFormat`](/references/iota-api/iota-graphql/reference/types/enums/domain-format) > > @@ -263,8 +267,8 @@ type Owner implements IOwner { #### [Owner.iotansRegistrations](#)[`IotansRegistrationConnection!`](/references/iota-api/iota-graphql/reference/types/objects/iotans-registration-connection) > > -> The IotansRegistration NFTs owned by this object or address. These grant the owner the -> capability to manage the associated domain. +> The IotansRegistration NFTs owned by this object or address. These grant +> the owner the capability to manage the associated domain. > ##### [Owner.iotansRegistrations.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -304,11 +308,12 @@ type Owner implements IOwner { #### [Owner.dynamicField](#)[`DynamicField`](/references/iota-api/iota-graphql/reference/types/objects/dynamic-field) > > -> Access a dynamic field on an object using its name. Names are arbitrary Move values whose -> type have `copy`, `drop`, and `store`, and are specified using their type, and their BCS -> contents, Base64 encoded. +> Access a dynamic field on an object using its name. Names are arbitrary +> Move values whose type have `copy`, `drop`, and `store`, and are +> specified using their type, and their BCS contents, Base64 encoded. > -> This field exists as a convenience when accessing a dynamic field on a wrapped object. +> This field exists as a convenience when accessing a dynamic field on a +> wrapped object. > ##### [Owner.dynamicField.name](#)[`DynamicFieldName!`](/references/iota-api/iota-graphql/reference/types/inputs/dynamic-field-name) > > @@ -318,12 +323,14 @@ type Owner implements IOwner { #### [Owner.dynamicObjectField](#)[`DynamicField`](/references/iota-api/iota-graphql/reference/types/objects/dynamic-field) > > -> Access a dynamic object field on an object using its name. Names are arbitrary Move values -> whose type have `copy`, `drop`, and `store`, and are specified using their type, and their -> BCS contents, Base64 encoded. The value of a dynamic object field can also be accessed +> Access a dynamic object field on an object using its name. Names are +> arbitrary Move values whose type have `copy`, `drop`, and `store`, +> and are specified using their type, and their BCS contents, Base64 +> encoded. The value of a dynamic object field can also be accessed > off-chain directly via its address (e.g. using `Query.object`). > -> This field exists as a convenience when accessing a dynamic field on a wrapped object. +> This field exists as a convenience when accessing a dynamic field on a +> wrapped object. > ##### [Owner.dynamicObjectField.name](#)[`DynamicFieldName!`](/references/iota-api/iota-graphql/reference/types/inputs/dynamic-field-name) > > @@ -335,7 +342,8 @@ type Owner implements IOwner { > > The dynamic fields and dynamic object fields on an object. > -> This field exists as a convenience when accessing a dynamic field on a wrapped object. +> This field exists as a convenience when accessing a dynamic field on a +> wrapped object. > ##### [Owner.dynamicFields.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -365,10 +373,11 @@ type Owner implements IOwner { #### [`IOwner`](/references/iota-api/iota-graphql/reference/types/interfaces/iowner) > > -> Interface implemented by GraphQL types representing entities that can own objects. Object owners -> are identified by an address which can represent either the public key of an account or another -> object. The same address can only refer to an account or an object, never both, but it is not -> possible to know which up-front. +> Interface implemented by GraphQL types representing entities that can own +> objects. Object owners are identified by an address which can represent +> either the public key of an account or another object. The same address can +> only refer to an account or an object, never both, but it is not possible to +> know which up-front. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/parent.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/parent.mdx index 4dcf9ca96eb..1175d7592af 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/parent.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/parent.mdx @@ -39,9 +39,10 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -If the object's owner is a Parent, this object is part of a dynamic field (it is the value of -the dynamic field, or the intermediate Field object itself). Also note that if the owner -is a parent, then it's guaranteed to be an object. +If the object's owner is a Parent, this object is part of a dynamic field +(it is the value of the dynamic field, or the intermediate Field object +itself). Also note that if the owner is a parent, then it's guaranteed to be +an object. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/programmable-transaction-block.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/programmable-transaction-block.mdx index 52d6a322c07..45b568c5429 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/programmable-transaction-block.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/programmable-transaction-block.mdx @@ -39,8 +39,9 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -A user transaction that allows the interleaving of native commands (like transfer, split coins, -merge coins, etc) and move calls, executed atomically. +A user transaction that allows the interleaving of native commands (like +transfer, split coins, merge coins, etc) and move calls, executed +atomically. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/protocol-configs.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/protocol-configs.mdx index a3c6462842a..ce779f9fed2 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/protocol-configs.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/protocol-configs.mdx @@ -41,7 +41,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => Constants that control how the chain operates. -These can only change during protocol upgrades which happen on epoch boundaries. +These can only change during protocol upgrades which happen on epoch +boundaries. ```graphql @@ -66,23 +67,26 @@ type ProtocolConfigs { #### [ProtocolConfigs.protocolVersion](#)[`Int!`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > -> The protocol is not required to change on every epoch boundary, so the protocol version -> tracks which change to the protocol these configs are from. +> The protocol is not required to change on every epoch boundary, so the +> protocol version tracks which change to the protocol these configs +> are from. > #### [ProtocolConfigs.featureFlags](#)[`[ProtocolConfigFeatureFlag!]!`](/references/iota-api/iota-graphql/reference/types/objects/protocol-config-feature-flag) > > -> List all available feature flags and their values. Feature flags are a form of boolean -> configuration that are usually used to gate features while they are in development. Once a -> flag has been enabled, it is rare for it to be disabled. +> List all available feature flags and their values. Feature flags are a +> form of boolean configuration that are usually used to gate features +> while they are in development. Once a flag has been enabled, it is +> rare for it to be disabled. > #### [ProtocolConfigs.configs](#)[`[ProtocolConfigAttr!]!`](/references/iota-api/iota-graphql/reference/types/objects/protocol-config-attr) > > -> List all available configurations and their values. These configurations can take any value -> (but they will all be represented in string form), and do not include feature flags. +> List all available configurations and their values. These +> configurations can take any value (but they will all be represented +> in string form), and do not include feature flags. > #### [ProtocolConfigs.config](#)[`ProtocolConfigAttr`](/references/iota-api/iota-graphql/reference/types/objects/protocol-config-attr) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/publish-transaction.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/publish-transaction.mdx index 5ec7ccbbafa..abdaf1917df 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/publish-transaction.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/publish-transaction.mdx @@ -57,7 +57,8 @@ type PublishTransaction { #### [PublishTransaction.modules](#)[`[Base64!]!`](/references/iota-api/iota-graphql/reference/types/scalars/base-64) > > -> Bytecode for the modules to be published, BCS serialized and Base64 encoded. +> Bytecode for the modules to be published, BCS serialized and Base64 +> encoded. > #### [PublishTransaction.dependencies](#)[`[IotaAddress!]!`](/references/iota-api/iota-graphql/reference/types/scalars/iota-address) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/receiving.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/receiving.mdx index 0e66060160f..d4d1037ae96 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/receiving.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/receiving.mdx @@ -71,8 +71,8 @@ type Receiving { #### [Receiving.digest](#)[`String!`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> 32-byte hash that identifies the object's contents at this version, encoded as a Base58 -> string. +> 32-byte hash that identifies the object's contents at this version, +> encoded as a Base58 string. > #### [Receiving.object](#)[`Object`](/references/iota-api/iota-graphql/reference/types/objects/object) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/result.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/result.mdx index d4d555f2ecf..133a917073a 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/result.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/result.mdx @@ -63,8 +63,9 @@ type Result { #### [Result.ix](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > -> If the previous command returns multiple values, this is the index of the individual result -> among the multiple results from that command (also 0-indexed). +> If the previous command returns multiple values, this is the index of +> the individual result among the multiple results from that command +> (also 0-indexed). > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/safe-mode.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/safe-mode.mdx index 9eff74b8a98..c88bce70aa1 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/safe-mode.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/safe-mode.mdx @@ -57,15 +57,17 @@ type SafeMode { #### [SafeMode.enabled](#)[`Boolean`](/references/iota-api/iota-graphql/reference/types/scalars/boolean) > > -> Whether safe mode was used for the last epoch change. The system will retry a full epoch -> change on every epoch boundary and automatically reset this flag if so. +> Whether safe mode was used for the last epoch change. The system will +> retry a full epoch change on every epoch boundary and automatically +> reset this flag if so. > #### [SafeMode.gasSummary](#)[`GasCostSummary`](/references/iota-api/iota-graphql/reference/types/objects/gas-cost-summary) > > -> Accumulated fees for computation and cost that have not been added to the various reward -> pools, because the full epoch change did not happen. +> Accumulated fees for computation and cost that have not been added to +> the various reward pools, because the full epoch change did not +> happen. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/service-config.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/service-config.mdx index ce125358c7a..3785f13c7ae 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/service-config.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/service-config.mdx @@ -93,7 +93,8 @@ type ServiceConfig { #### [ServiceConfig.maxQueryNodes](#)[`Int!`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > -> The maximum number of nodes (field names) the service will accept in a single query. +> The maximum number of nodes (field names) the service will accept in a +> single query. > #### [ServiceConfig.maxOutputNodes](#)[`Int!`](/references/iota-api/iota-graphql/reference/types/scalars/int) @@ -101,21 +102,24 @@ type ServiceConfig { > > The maximum number of output nodes in a GraphQL response. > -> Non-connection nodes have a count of 1, while connection nodes are counted as -> the specified 'first' or 'last' number of items, or the default_page_size -> as set by the server if those arguments are not set. +> Non-connection nodes have a count of 1, while connection nodes are +> counted as the specified 'first' or 'last' number of items, or the +> default_page_size as set by the server if those arguments are not +> set. > -> Counts accumulate multiplicatively down the query tree. For example, if a query starts -> with a connection of first: 10 and has a field to a connection with last: 20, the count -> at the second level would be 200 nodes. This is then summed to the count of 10 nodes -> at the first level, for a total of 210 nodes. +> Counts accumulate multiplicatively down the query tree. For example, if +> a query starts with a connection of first: 10 and has a field to a +> connection with last: 20, the count at the second level would be 200 +> nodes. This is then summed to the count of 10 nodes at the first +> level, for a total of 210 nodes. > #### [ServiceConfig.maxDbQueryCost](#)[`BigInt!`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> Maximum estimated cost of a database query used to serve a GraphQL request. This is -> measured in the same units that the database uses in EXPLAIN queries. +> Maximum estimated cost of a database query used to serve a GraphQL +> request. This is measured in the same units that the database uses +> in EXPLAIN queries. > #### [ServiceConfig.defaultPageSize](#)[`Int!`](/references/iota-api/iota-graphql/reference/types/scalars/int) @@ -145,27 +149,29 @@ type ServiceConfig { #### [ServiceConfig.maxTypeArgumentDepth](#)[`Int!`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > -> Maximum nesting allowed in type arguments in Move Types resolved by this service. +> Maximum nesting allowed in type arguments in Move Types resolved by this +> service. > #### [ServiceConfig.maxTypeArgumentWidth](#)[`Int!`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > -> Maximum number of type arguments passed into a generic instantiation of a Move Type resolved -> by this service. +> Maximum number of type arguments passed into a generic instantiation of +> a Move Type resolved by this service. > #### [ServiceConfig.maxTypeNodes](#)[`Int!`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > -> Maximum number of structs that need to be processed when calculating the layout of a single -> Move Type. +> Maximum number of structs that need to be processed when calculating the +> layout of a single Move Type. > #### [ServiceConfig.maxMoveValueDepth](#)[`Int!`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > -> Maximum nesting allowed in struct fields when calculating the layout of a single Move Type. +> Maximum nesting allowed in struct fields when calculating the layout of +> a single Move Type. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/shared-input.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/shared-input.mdx index 87ec5f5bc8e..ef4a7641494 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/shared-input.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/shared-input.mdx @@ -70,11 +70,12 @@ type SharedInput { #### [SharedInput.mutable](#)[`Boolean!`](/references/iota-api/iota-graphql/reference/types/scalars/boolean) > > -> Controls whether the transaction block can reference the shared object as a mutable -> reference or by value. This has implications for scheduling: Transactions that just read -> shared objects at a certain version (mutable = false) can be executed concurrently, while -> transactions that write shared objects (mutable = true) must be executed serially with -> respect to each other. +> Controls whether the transaction block can reference the shared object +> as a mutable reference or by value. This has implications for +> scheduling: Transactions that just read shared objects at a certain +> version (mutable = false) can be executed concurrently, while +> transactions that write shared objects (mutable = true) must be executed +> serially with respect to each other. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/shared-object-delete.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/shared-object-delete.mdx index 1bb8f99cf97..e0a44703318 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/shared-object-delete.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/shared-object-delete.mdx @@ -39,8 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -The transaction accepted a shared object as input, but it was deleted before the transaction -executed. +The transaction accepted a shared object as input, but it was deleted before +the transaction executed. ```graphql @@ -65,15 +65,15 @@ type SharedObjectDelete { #### [SharedObjectDelete.version](#)[`Int!`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > -> The version of the shared object that was assigned to this transaction during by consensus, -> during sequencing. +> The version of the shared object that was assigned to this transaction +> during by consensus, during sequencing. > #### [SharedObjectDelete.mutable](#)[`Boolean!`](/references/iota-api/iota-graphql/reference/types/scalars/boolean) > > -> Whether this transaction intended to use this shared object mutably or not. See -> `SharedInput.mutable` for further details. +> Whether this transaction intended to use this shared object mutably or +> not. See `SharedInput.mutable` for further details. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/shared-object-read.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/shared-object-read.mdx index e7eb843f51e..334eae891af 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/shared-object-read.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/shared-object-read.mdx @@ -71,8 +71,8 @@ type SharedObjectRead { #### [SharedObjectRead.digest](#)[`String!`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> 32-byte hash that identifies the object's contents at this version, encoded as a Base58 -> string. +> 32-byte hash that identifies the object's contents at this version, +> encoded as a Base58 string. > #### [SharedObjectRead.object](#)[`Object`](/references/iota-api/iota-graphql/reference/types/objects/object) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/shared.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/shared.mdx index 531be5c98d6..3afafcf58a0 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/shared.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/shared.mdx @@ -39,8 +39,9 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -A shared object is an object that is shared using the 0x2::transfer::share_object function. -Unlike owned objects, once an object is shared, it stays mutable and is accessible by anyone. +A shared object is an object that is shared using the +0x2::transfer::share_object function. Unlike owned objects, once an object +is shared, it stays mutable and is accessible by anyone. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/split-coins-transaction.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/split-coins-transaction.mdx index e4f29f42945..46802737c08 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/split-coins-transaction.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/split-coins-transaction.mdx @@ -39,8 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Splits off coins with denominations in `amounts` from `coin`, returning multiple results (as -many as there are amounts.) +Splits off coins with denominations in `amounts` from `coin`, returning +multiple results (as many as there are amounts.) ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/stake-subsidy.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/stake-subsidy.mdx index e18d6c61699..323e67483c5 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/stake-subsidy.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/stake-subsidy.mdx @@ -60,35 +60,36 @@ type StakeSubsidy { #### [StakeSubsidy.balance](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> IOTA set aside for stake subsidies -- reduces over time as stake subsidies are paid out over -> time. +> IOTA set aside for stake subsidies -- reduces over time as stake +> subsidies are paid out over time. > #### [StakeSubsidy.distributionCounter](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > -> Number of times stake subsidies have been distributed subsidies are distributed with other -> staking rewards, at the end of the epoch. +> Number of times stake subsidies have been distributed subsidies are +> distributed with other staking rewards, at the end of the epoch. > #### [StakeSubsidy.currentDistributionAmount](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> Amount of stake subsidy deducted from the balance per distribution -- decays over time. +> Amount of stake subsidy deducted from the balance per distribution -- +> decays over time. > #### [StakeSubsidy.periodLength](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > -> Maximum number of stake subsidy distributions that occur with the same distribution amount -> (before the amount is reduced). +> Maximum number of stake subsidy distributions that occur with the same +> distribution amount (before the amount is reduced). > #### [StakeSubsidy.decreaseRate](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > -> Percentage of the current distribution amount to deduct at the end of the current subsidy -> period, expressed in basis points. +> Percentage of the current distribution amount to deduct at the end of +> the current subsidy period, expressed in basis points. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/staked-iota.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/staked-iota.mdx index 0b547e86b80..7c25ffa67ac 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/staked-iota.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/staked-iota.mdx @@ -169,8 +169,8 @@ type StakedIota implements IMoveObject, IObject, IOwner { #### [StakedIota.balance](#)[`Balance`](/references/iota-api/iota-graphql/reference/types/objects/balance) > > -> Total balance of all coins with marker type owned by this object. If type is not supplied, -> it defaults to `0x2::iota::IOTA`. +> Total balance of all coins with marker type owned by this object. If +> type is not supplied, it defaults to `0x2::iota::IOTA`. > ##### [StakedIota.balance.type](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > @@ -210,7 +210,8 @@ type StakedIota implements IMoveObject, IObject, IOwner { > > The coin objects for this object. > -> `type` is a filter on the coin's type parameter, defaulting to `0x2::iota::IOTA`. +> `type` is a filter on the coin's type parameter, defaulting to +> `0x2::iota::IOTA`. > ##### [StakedIota.coins.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -272,7 +273,8 @@ type StakedIota implements IMoveObject, IObject, IOwner { #### [StakedIota.defaultIotansName](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> The domain explicitly configured as the default domain pointing to this object. +> The domain explicitly configured as the default domain pointing to this +> object. > ##### [StakedIota.defaultIotansName.format](#)[`DomainFormat`](/references/iota-api/iota-graphql/reference/types/enums/domain-format) > > @@ -282,8 +284,8 @@ type StakedIota implements IMoveObject, IObject, IOwner { #### [StakedIota.iotansRegistrations](#)[`IotansRegistrationConnection!`](/references/iota-api/iota-graphql/reference/types/objects/iotans-registration-connection) > > -> The IotansRegistration NFTs owned by this object. These grant the owner the capability to -> manage the associated domain. +> The IotansRegistration NFTs owned by this object. These grant the owner +> the capability to manage the associated domain. > ##### [StakedIota.iotansRegistrations.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -317,19 +319,22 @@ type StakedIota implements IMoveObject, IObject, IOwner { #### [StakedIota.status](#)[`ObjectKind!`](/references/iota-api/iota-graphql/reference/types/enums/object-kind) > > -> The current status of the object as read from the off-chain store. The possible states are: -> NOT_INDEXED, the object is loaded from serialized data, such as the contents of a genesis or -> system package upgrade transaction. LIVE, the version returned is the most recent for the -> object, and it is not deleted or wrapped at that version. HISTORICAL, the object was -> referenced at a specific version or checkpoint, so is fetched from historical tables and may -> not be the latest version of the object. WRAPPED_OR_DELETED, the object is deleted or -> wrapped and only partial information can be loaded." +> The current status of the object as read from the off-chain store. The +> possible states are: NOT_INDEXED, the object is loaded from +> serialized data, such as the contents of a genesis or system package +> upgrade transaction. LIVE, the version returned is the most recent for +> the object, and it is not deleted or wrapped at that version. +> HISTORICAL, the object was referenced at a specific version or +> checkpoint, so is fetched from historical tables and may not be the +> latest version of the object. WRAPPED_OR_DELETED, the object is deleted +> or wrapped and only partial information can be loaded." > #### [StakedIota.digest](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> 32-byte hash that identifies the object's contents, encoded as a Base58 string. +> 32-byte hash that identifies the object's contents, encoded as a Base58 +> string. > #### [StakedIota.owner](#)[`ObjectOwner`](/references/iota-api/iota-graphql/reference/types/unions/object-owner) @@ -347,8 +352,9 @@ type StakedIota implements IMoveObject, IObject, IOwner { #### [StakedIota.storageRebate](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> The amount of IOTA we would rebate if this object gets deleted or mutated. This number is -> recalculated based on the present storage gas price. +> The amount of IOTA we would rebate if this object gets deleted or +> mutated. This number is recalculated based on the present storage +> gas price. > #### [StakedIota.receivedTransactionBlocks](#)[`TransactionBlockConnection!`](/references/iota-api/iota-graphql/reference/types/objects/transaction-block-connection) @@ -394,36 +400,37 @@ type StakedIota implements IMoveObject, IObject, IOwner { #### [StakedIota.contents](#)[`MoveValue`](/references/iota-api/iota-graphql/reference/types/objects/move-value) > > -> Displays the contents of the Move object in a JSON string and through GraphQL types. Also -> provides the flat representation of the type signature, and the BCS of the corresponding -> data. +> Displays the contents of the Move object in a JSON string and through +> GraphQL types. Also provides the flat representation of the type +> signature, and the BCS of the corresponding data. > #### [StakedIota.hasPublicTransfer](#)[`Boolean!`](/references/iota-api/iota-graphql/reference/types/scalars/boolean) > > -> Determines whether a transaction can transfer this object, using the TransferObjects -> transaction command or `iota::transfer::public_transfer`, both of which require the object to +> Determines whether a transaction can transfer this object, using the +> TransferObjects transaction command or +> `iota::transfer::public_transfer`, both of which require the object to > have the `key` and `store` abilities. > #### [StakedIota.display](#)[`[DisplayEntry!]`](/references/iota-api/iota-graphql/reference/types/objects/display-entry) > > -> The set of named templates defined on-chain for the type of this object, to be handled -> off-chain. The server substitutes data from the object into these templates to generate a -> display string per template. +> The set of named templates defined on-chain for the type of this object, +> to be handled off-chain. The server substitutes data from the object +> into these templates to generate a display string per template. > #### [StakedIota.dynamicField](#)[`DynamicField`](/references/iota-api/iota-graphql/reference/types/objects/dynamic-field) > > -> Access a dynamic field on an object using its name. Names are arbitrary Move values whose -> type have `copy`, `drop`, and `store`, and are specified using their type, and their BCS -> contents, Base64 encoded. +> Access a dynamic field on an object using its name. Names are arbitrary +> Move values whose type have `copy`, `drop`, and `store`, and are +> specified using their type, and their BCS contents, Base64 encoded. > -> Dynamic fields on wrapped objects can be accessed by using the same API under the Owner -> type. +> Dynamic fields on wrapped objects can be accessed by using the same API +> under the Owner type. > ##### [StakedIota.dynamicField.name](#)[`DynamicFieldName!`](/references/iota-api/iota-graphql/reference/types/inputs/dynamic-field-name) > > @@ -433,13 +440,14 @@ type StakedIota implements IMoveObject, IObject, IOwner { #### [StakedIota.dynamicObjectField](#)[`DynamicField`](/references/iota-api/iota-graphql/reference/types/objects/dynamic-field) > > -> Access a dynamic object field on an object using its name. Names are arbitrary Move values -> whose type have `copy`, `drop`, and `store`, and are specified using their type, and their -> BCS contents, Base64 encoded. The value of a dynamic object field can also be accessed +> Access a dynamic object field on an object using its name. Names are +> arbitrary Move values whose type have `copy`, `drop`, and `store`, +> and are specified using their type, and their BCS contents, Base64 +> encoded. The value of a dynamic object field can also be accessed > off-chain directly via its address (e.g. using `Query.object`). > -> Dynamic fields on wrapped objects can be accessed by using the same API under the Owner -> type. +> Dynamic fields on wrapped objects can be accessed by using the same API +> under the Owner type. > ##### [StakedIota.dynamicObjectField.name](#)[`DynamicFieldName!`](/references/iota-api/iota-graphql/reference/types/inputs/dynamic-field-name) > > @@ -451,8 +459,8 @@ type StakedIota implements IMoveObject, IObject, IOwner { > > The dynamic fields and dynamic object fields on an object. > -> Dynamic fields on wrapped objects can be accessed by using the same API under the Owner -> type. +> Dynamic fields on wrapped objects can be accessed by using the same API +> under the Owner type. > ##### [StakedIota.dynamicFields.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -516,7 +524,8 @@ type StakedIota implements IMoveObject, IObject, IOwner { > > Or 0, if this value is negative, where: > -> - `initial_stake_rate` is the stake rate at the epoch this stake was activated at. +> - `initial_stake_rate` is the stake rate at the epoch this stake was +> activated at. > - `current_stake_rate` is the stake rate in the current epoch. > > This value is only available if the stake is active. @@ -527,24 +536,25 @@ type StakedIota implements IMoveObject, IObject, IOwner { #### [`IMoveObject`](/references/iota-api/iota-graphql/reference/types/interfaces/imove-object) > > -> This interface is implemented by types that represent a Move object on-chain (A Move value whose -> type has `key`). +> This interface is implemented by types that represent a Move object on-chain +> (A Move value whose type has `key`). > #### [`IObject`](/references/iota-api/iota-graphql/reference/types/interfaces/iobject) > > -> Interface implemented by on-chain values that are addressable by an ID (also referred to as its -> address). This includes Move objects and packages. +> Interface implemented by on-chain values that are addressable by an ID (also +> referred to as its address). This includes Move objects and packages. > #### [`IOwner`](/references/iota-api/iota-graphql/reference/types/interfaces/iowner) > > -> Interface implemented by GraphQL types representing entities that can own objects. Object owners -> are identified by an address which can represent either the public key of an account or another -> object. The same address can only refer to an account or an object, never both, but it is not -> possible to know which up-front. +> Interface implemented by GraphQL types representing entities that can own +> objects. Object owners are identified by an address which can represent +> either the public key of an account or another object. The same address can +> only refer to an account or an object, never both, but it is not possible to +> know which up-front. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/storage-fund.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/storage-fund.mdx index 2aadd9f9197..2bcc1dd63a4 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/storage-fund.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/storage-fund.mdx @@ -63,11 +63,12 @@ type StorageFund { #### [StorageFund.nonRefundableBalance](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> The portion of the storage fund that will never be refunded through storage rebates. +> The portion of the storage fund that will never be refunded through +> storage rebates. > -> The system maintains an invariant that the sum of all storage fees into the storage fund is -> equal to the sum of of all storage rebates out, the total storage rebates remaining, and the -> non-refundable balance. +> The system maintains an invariant that the sum of all storage fees into +> the storage fund is equal to the sum of of all storage rebates out, +> the total storage rebates remaining, and the non-refundable balance. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/system-parameters.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/system-parameters.mdx index 20180921ee1..60cbdc8dead 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/system-parameters.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/system-parameters.mdx @@ -93,22 +93,24 @@ type SystemParameters { #### [SystemParameters.validatorLowStakeThreshold](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> Validators with stake below this threshold will enter the grace period (see -> `validatorLowStakeGracePeriod`), after which they are removed from the active validator set. +> Validators with stake below this threshold will enter the grace period +> (see `validatorLowStakeGracePeriod`), after which they are removed +> from the active validator set. > #### [SystemParameters.validatorVeryLowStakeThreshold](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> Validators with stake below this threshold will be removed from the active validator set -> at the next epoch boundary, without a grace period. +> Validators with stake below this threshold will be removed from the +> active validator set at the next epoch boundary, without a grace +> period. > #### [SystemParameters.validatorLowStakeGracePeriod](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> The number of epochs that a validator has to recover from having less than -> `validatorLowStakeThreshold` stake. +> The number of epochs that a validator has to recover from having less +> than `validatorLowStakeThreshold` stake. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/transaction-block-effects.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/transaction-block-effects.mdx index c76f15b114c..9aefd6d0eda 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/transaction-block-effects.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/transaction-block-effects.mdx @@ -106,8 +106,9 @@ type TransactionBlockEffects { #### [TransactionBlockEffects.lamportVersion](#)[`Int!`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > -> The latest version of all objects (apart from packages) that have been created or modified -> by this transaction, immediately following this transaction. +> The latest version of all objects (apart from packages) that have been +> created or modified by this transaction, immediately following this +> transaction. > #### [TransactionBlockEffects.errors](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) @@ -153,7 +154,8 @@ type TransactionBlockEffects { #### [TransactionBlockEffects.unchangedSharedObjects](#)[`UnchangedSharedObjectConnection!`](/references/iota-api/iota-graphql/reference/types/objects/unchanged-shared-object-connection) > > -> Shared objects that are referenced by but not changed by this transaction. +> Shared objects that are referenced by but not changed by this +> transaction. > ##### [TransactionBlockEffects.unchangedSharedObjects.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -209,8 +211,8 @@ type TransactionBlockEffects { #### [TransactionBlockEffects.balanceChanges](#)[`BalanceChangeConnection!`](/references/iota-api/iota-graphql/reference/types/objects/balance-change-connection) > > -> The effect this transaction had on the balances (sum of coin values per coin type) of -> addresses and objects. +> The effect this transaction had on the balances (sum of coin values per +> coin type) of addresses and objects. > ##### [TransactionBlockEffects.balanceChanges.first](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > @@ -266,7 +268,8 @@ type TransactionBlockEffects { #### [TransactionBlockEffects.timestamp](#)[`DateTime`](/references/iota-api/iota-graphql/reference/types/scalars/date-time) > > -> Timestamp corresponding to the checkpoint this transaction was finalized in. +> Timestamp corresponding to the checkpoint this transaction was finalized +> in. > #### [TransactionBlockEffects.epoch](#)[`Epoch`](/references/iota-api/iota-graphql/reference/types/objects/epoch) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/transaction-block.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/transaction-block.mdx index e386123c380..1ca80320dcf 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/transaction-block.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/transaction-block.mdx @@ -63,59 +63,64 @@ type TransactionBlock { #### [TransactionBlock.digest](#)[`String`](/references/iota-api/iota-graphql/reference/types/scalars/string) > > -> A 32-byte hash that uniquely identifies the transaction block contents, encoded in Base58. -> This serves as a unique id for the block on chain. +> A 32-byte hash that uniquely identifies the transaction block contents, +> encoded in Base58. This serves as a unique id for the block on +> chain. > #### [TransactionBlock.sender](#)[`Address`](/references/iota-api/iota-graphql/reference/types/objects/address) > > -> The address corresponding to the public key that signed this transaction. System -> transactions do not have senders. +> The address corresponding to the public key that signed this +> transaction. System transactions do not have senders. > #### [TransactionBlock.gasInput](#)[`GasInput`](/references/iota-api/iota-graphql/reference/types/objects/gas-input) > > -> The gas input field provides information on what objects were used as gas as well as the -> owner of the gas object(s) and information on the gas price and budget. +> The gas input field provides information on what objects were used as +> gas as well as the owner of the gas object(s) and information on the +> gas price and budget. > -> If the owner of the gas object(s) is not the same as the sender, the transaction block is a -> sponsored transaction block. +> If the owner of the gas object(s) is not the same as the sender, the +> transaction block is a sponsored transaction block. > #### [TransactionBlock.kind](#)[`TransactionBlockKind`](/references/iota-api/iota-graphql/reference/types/unions/transaction-block-kind) > > -> The type of this transaction as well as the commands and/or parameters comprising the -> transaction of this kind. +> The type of this transaction as well as the commands and/or parameters +> comprising the transaction of this kind. > #### [TransactionBlock.signatures](#)[`[Base64!]`](/references/iota-api/iota-graphql/reference/types/scalars/base-64) > > -> A list of all signatures, Base64-encoded, from senders, and potentially the gas owner if -> this is a sponsored transaction. +> A list of all signatures, Base64-encoded, from senders, and potentially +> the gas owner if this is a sponsored transaction. > #### [TransactionBlock.effects](#)[`TransactionBlockEffects`](/references/iota-api/iota-graphql/reference/types/objects/transaction-block-effects) > > -> The effects field captures the results to the chain of executing this transaction. +> The effects field captures the results to the chain of executing this +> transaction. > #### [TransactionBlock.expiration](#)[`Epoch`](/references/iota-api/iota-graphql/reference/types/objects/epoch) > > -> This field is set by senders of a transaction block. It is an epoch reference that sets a -> deadline after which validators will no longer consider the transaction valid. By default, -> there is no deadline for when a transaction must execute. +> This field is set by senders of a transaction block. It is an epoch +> reference that sets a deadline after which validators will no longer +> consider the transaction valid. By default, there is no deadline for +> when a transaction must execute. > #### [TransactionBlock.bcs](#)[`Base64`](/references/iota-api/iota-graphql/reference/types/scalars/base-64) > > -> Serialized form of this transaction's `SenderSignedData`, BCS serialized and Base64 encoded. +> Serialized form of this transaction's `SenderSignedData`, BCS serialized +> and Base64 encoded. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/transfer-objects-transaction.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/transfer-objects-transaction.mdx index d6e6fbdeed9..0ad0f47f472 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/transfer-objects-transaction.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/transfer-objects-transaction.mdx @@ -39,8 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Transfers `inputs` to `address`. All inputs must have the `store` ability (allows public -transfer) and must not be previously immutable or shared. +Transfers `inputs` to `address`. All inputs must have the `store` ability +(allows public transfer) and must not be previously immutable or shared. ```graphql diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/upgrade-transaction.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/upgrade-transaction.mdx index dc72a1d46e8..7e12fc5679a 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/upgrade-transaction.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/upgrade-transaction.mdx @@ -59,7 +59,8 @@ type UpgradeTransaction { #### [UpgradeTransaction.modules](#)[`[Base64!]!`](/references/iota-api/iota-graphql/reference/types/scalars/base-64) > > -> Bytecode for the modules to be published, BCS serialized and Base64 encoded. +> Bytecode for the modules to be published, BCS serialized and Base64 +> encoded. > #### [UpgradeTransaction.dependencies](#)[`[IotaAddress!]!`](/references/iota-api/iota-graphql/reference/types/scalars/iota-address) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/validator-set.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/validator-set.mdx index c610e691c04..e727893f670 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/validator-set.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/validator-set.mdx @@ -71,20 +71,22 @@ type ValidatorSet { #### [ValidatorSet.totalStake](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> Total amount of stake for all active validators at the beginning of the epoch. +> Total amount of stake for all active validators at the beginning of the +> epoch. > #### [ValidatorSet.pendingRemovals](#)[`[Int!]`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > -> Validators that are pending removal from the active validator set, expressed as indices in -> to `activeValidators`. +> Validators that are pending removal from the active validator set, +> expressed as indices in to `activeValidators`. > #### [ValidatorSet.pendingActiveValidatorsId](#)[`IotaAddress`](/references/iota-api/iota-graphql/reference/types/scalars/iota-address) > > -> Object ID of the wrapped object `TableVec` storing the pending active validators. +> Object ID of the wrapped object `TableVec` storing the pending active +> validators. > #### [ValidatorSet.pendingActiveValidatorsSize](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) @@ -96,9 +98,10 @@ type ValidatorSet { #### [ValidatorSet.stakingPoolMappingsId](#)[`IotaAddress`](/references/iota-api/iota-graphql/reference/types/scalars/iota-address) > > -> Object ID of the `Table` storing the mapping from staking pool ids to the addresses -> of the corresponding validators. This is needed because a validator's address -> can potentially change but the object ID of its pool will not. +> Object ID of the `Table` storing the mapping from staking pool ids to +> the addresses of the corresponding validators. This is needed +> because a validator's address can potentially change but the object +> ID of its pool will not. > #### [ValidatorSet.stakingPoolMappingsSize](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/objects/validator.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/objects/validator.mdx index 25d7dc8e3d4..6c01322ffd3 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/objects/validator.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/objects/validator.mdx @@ -93,7 +93,8 @@ type Validator { #### [Validator.credentials](#)[`ValidatorCredentials`](/references/iota-api/iota-graphql/reference/types/objects/validator-credentials) > > -> Validator's set of credentials such as public keys, network addresses and others. +> Validator's set of credentials such as public keys, network addresses +> and others. > #### [Validator.nextEpochCredentials](#)[`ValidatorCredentials`](/references/iota-api/iota-graphql/reference/types/objects/validator-credentials) @@ -130,22 +131,24 @@ type Validator { > > > The validator's current valid `Cap` object. Validators can delegate -> the operation ability to another address. The address holding this `Cap` object -> can then update the reference gas price and tallying rule on behalf of the validator. +> the operation ability to another address. The address holding this `Cap` +> object can then update the reference gas price and tallying rule on +> behalf of the validator. > #### [Validator.stakingPool](#)[`MoveObject`](/references/iota-api/iota-graphql/reference/types/objects/move-object) > > -> The validator's current staking pool object, used to track the amount of stake -> and to compound staking rewards. +> The validator's current staking pool object, used to track the amount of +> stake and to compound staking rewards. > #### [Validator.exchangeRates](#)[`MoveObject`](/references/iota-api/iota-graphql/reference/types/objects/move-object) > > -> The validator's current exchange object. The exchange rate is used to determine -> the amount of IOTA tokens that each past IOTA staker can withdraw in the future. +> The validator's current exchange object. The exchange rate is used to +> determine the amount of IOTA tokens that each past IOTA staker can +> withdraw in the future. > #### [Validator.exchangeRatesSize](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) @@ -187,19 +190,22 @@ type Validator { #### [Validator.pendingTotalIotaWithdraw](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> Pending stake withdrawn during the current epoch, emptied at epoch boundaries. +> Pending stake withdrawn during the current epoch, emptied at epoch +> boundaries. > #### [Validator.pendingPoolTokenWithdraw](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) > > -> Pending pool token withdrawn during the current epoch, emptied at epoch boundaries. +> Pending pool token withdrawn during the current epoch, emptied at epoch +> boundaries. > #### [Validator.votingPower](#)[`Int`](/references/iota-api/iota-graphql/reference/types/scalars/int) > > -> The voting power of this validator in basis points (e.g., 100 = 1% voting power). +> The voting power of this validator in basis points (e.g., 100 = 1% +> voting power). > #### [Validator.gasPrice](#)[`BigInt`](/references/iota-api/iota-graphql/reference/types/scalars/big-int) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/unions/dynamic-field-value.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/unions/dynamic-field-value.mdx index 9b4d4a95db8..4304222b58b 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/unions/dynamic-field-value.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/unions/dynamic-field-value.mdx @@ -54,8 +54,9 @@ union DynamicFieldValue = MoveObject | MoveValue #### [DynamicFieldValue.MoveObject](/references/iota-api/iota-graphql/reference/types/objects/move-object) > > -> The representation of an object as a Move Object, which exposes additional information -> (content, module that governs it, version, is transferrable, etc.) about this object. +> The representation of an object as a Move Object, which exposes additional +> information (content, module that governs it, version, is transferrable, +> etc.) about this object. > #### [DynamicFieldValue.MoveValue](/references/iota-api/iota-graphql/reference/types/objects/move-value) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/unions/end-of-epoch-transaction-kind.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/unions/end-of-epoch-transaction-kind.mdx index 198446394c2..91b5ddd2e08 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/unions/end-of-epoch-transaction-kind.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/unions/end-of-epoch-transaction-kind.mdx @@ -54,9 +54,10 @@ union EndOfEpochTransactionKind = ChangeEpochTransaction | AuthenticatorStateCre #### [EndOfEpochTransactionKind.ChangeEpochTransaction](/references/iota-api/iota-graphql/reference/types/objects/change-epoch-transaction) > > -> A system transaction that updates epoch information on-chain (increments the current epoch). -> Executed by the system once per epoch, without using gas. Epoch change transactions cannot be -> submitted by users, because validators will refuse to sign them. +> A system transaction that updates epoch information on-chain (increments the +> current epoch). Executed by the system once per epoch, without using gas. +> Epoch change transactions cannot be submitted by users, because validators +> will refuse to sign them. > > This transaction kind is deprecated in favour of `EndOfEpochTransaction`. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/unions/object-owner.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/unions/object-owner.mdx index 193e0797263..0ec639dc8d4 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/unions/object-owner.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/unions/object-owner.mdx @@ -54,23 +54,25 @@ union ObjectOwner = Immutable | Shared | Parent | AddressOwner #### [ObjectOwner.Immutable](/references/iota-api/iota-graphql/reference/types/objects/immutable) > > -> An immutable object is an object that can't be mutated, transferred, or deleted. -> Immutable objects have no owner, so anyone can use them. +> An immutable object is an object that can't be mutated, transferred, or +> deleted. Immutable objects have no owner, so anyone can use them. > #### [ObjectOwner.Shared](/references/iota-api/iota-graphql/reference/types/objects/shared) > > -> A shared object is an object that is shared using the 0x2::transfer::share_object function. -> Unlike owned objects, once an object is shared, it stays mutable and is accessible by anyone. +> A shared object is an object that is shared using the +> 0x2::transfer::share_object function. Unlike owned objects, once an object +> is shared, it stays mutable and is accessible by anyone. > #### [ObjectOwner.Parent](/references/iota-api/iota-graphql/reference/types/objects/parent) > > -> If the object's owner is a Parent, this object is part of a dynamic field (it is the value of -> the dynamic field, or the intermediate Field object itself). Also note that if the owner -> is a parent, then it's guaranteed to be an object. +> If the object's owner is a Parent, this object is part of a dynamic field +> (it is the value of the dynamic field, or the intermediate Field object +> itself). Also note that if the owner is a parent, then it's guaranteed to be +> an object. > #### [ObjectOwner.AddressOwner](/references/iota-api/iota-graphql/reference/types/objects/address-owner) @@ -78,7 +80,8 @@ union ObjectOwner = Immutable | Shared | Parent | AddressOwner > > An address-owned object is owned by a specific 32-byte address that is > either an account address (derived from a particular signature scheme) or -> an object ID. An address-owned object is accessible only to its owner and no others. +> an object ID. An address-owned object is accessible only to its owner and no +> others. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/unions/programmable-transaction.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/unions/programmable-transaction.mdx index 7562151bcf4..9fdc8a0f3f1 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/unions/programmable-transaction.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/unions/programmable-transaction.mdx @@ -60,15 +60,15 @@ union ProgrammableTransaction = MoveCallTransaction | TransferObjectsTransaction #### [ProgrammableTransaction.TransferObjectsTransaction](/references/iota-api/iota-graphql/reference/types/objects/transfer-objects-transaction) > > -> Transfers `inputs` to `address`. All inputs must have the `store` ability (allows public -> transfer) and must not be previously immutable or shared. +> Transfers `inputs` to `address`. All inputs must have the `store` ability +> (allows public transfer) and must not be previously immutable or shared. > #### [ProgrammableTransaction.SplitCoinsTransaction](/references/iota-api/iota-graphql/reference/types/objects/split-coins-transaction) > > -> Splits off coins with denominations in `amounts` from `coin`, returning multiple results (as -> many as there are amounts.) +> Splits off coins with denominations in `amounts` from `coin`, returning +> multiple results (as many as there are amounts.) > #### [ProgrammableTransaction.MergeCoinsTransaction](/references/iota-api/iota-graphql/reference/types/objects/merge-coins-transaction) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/unions/transaction-argument.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/unions/transaction-argument.mdx index 9ac679aa5c1..9e10b32fd29 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/unions/transaction-argument.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/unions/transaction-argument.mdx @@ -54,14 +54,16 @@ union TransactionArgument = GasCoin | Input | Result #### [TransactionArgument.GasCoin](/references/iota-api/iota-graphql/reference/types/objects/gas-coin) > > -> Access to the gas inputs, after they have been smashed into one coin. The gas coin can only be -> used by reference, except for with `TransferObjectsTransaction` that can accept it by value. +> Access to the gas inputs, after they have been smashed into one coin. The +> gas coin can only be used by reference, except for with +> `TransferObjectsTransaction` that can accept it by value. > #### [TransactionArgument.Input](/references/iota-api/iota-graphql/reference/types/objects/input) > > -> One of the input objects or primitive values to the programmable transaction block. +> One of the input objects or primitive values to the programmable transaction +> block. > #### [TransactionArgument.Result](/references/iota-api/iota-graphql/reference/types/objects/result) diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/unions/transaction-block-kind.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/unions/transaction-block-kind.mdx index d8f0f109252..7287ac84e33 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/unions/transaction-block-kind.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/unions/transaction-block-kind.mdx @@ -39,7 +39,8 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -The kind of transaction block, either a programmable transaction or a system transaction. +The kind of transaction block, either a programmable transaction or a system +transaction. ```graphql @@ -54,22 +55,25 @@ union TransactionBlockKind = ConsensusCommitPrologueTransaction | GenesisTransac #### [TransactionBlockKind.ConsensusCommitPrologueTransaction](/references/iota-api/iota-graphql/reference/types/objects/consensus-commit-prologue-transaction) > > -> System transaction that runs at the beginning of a checkpoint, and is responsible for setting -> the current value of the clock, based on the timestamp from consensus. +> System transaction that runs at the beginning of a checkpoint, and is +> responsible for setting the current value of the clock, based on the +> timestamp from consensus. > #### [TransactionBlockKind.GenesisTransaction](/references/iota-api/iota-graphql/reference/types/objects/genesis-transaction) > > -> System transaction that initializes the network and writes the initial set of objects on-chain. +> System transaction that initializes the network and writes the initial set +> of objects on-chain. > #### [TransactionBlockKind.ChangeEpochTransaction](/references/iota-api/iota-graphql/reference/types/objects/change-epoch-transaction) > > -> A system transaction that updates epoch information on-chain (increments the current epoch). -> Executed by the system once per epoch, without using gas. Epoch change transactions cannot be -> submitted by users, because validators will refuse to sign them. +> A system transaction that updates epoch information on-chain (increments the +> current epoch). Executed by the system once per epoch, without using gas. +> Epoch change transactions cannot be submitted by users, because validators +> will refuse to sign them. > > This transaction kind is deprecated in favour of `EndOfEpochTransaction`. > @@ -77,8 +81,9 @@ union TransactionBlockKind = ConsensusCommitPrologueTransaction | GenesisTransac #### [TransactionBlockKind.ProgrammableTransactionBlock](/references/iota-api/iota-graphql/reference/types/objects/programmable-transaction-block) > > -> A user transaction that allows the interleaving of native commands (like transfer, split coins, -> merge coins, etc) and move calls, executed atomically. +> A user transaction that allows the interleaving of native commands (like +> transfer, split coins, merge coins, etc) and move calls, executed +> atomically. > #### [TransactionBlockKind.AuthenticatorStateUpdateTransaction](/references/iota-api/iota-graphql/reference/types/objects/authenticator-state-update-transaction) @@ -96,9 +101,10 @@ union TransactionBlockKind = ConsensusCommitPrologueTransaction | GenesisTransac #### [TransactionBlockKind.EndOfEpochTransaction](/references/iota-api/iota-graphql/reference/types/objects/end-of-epoch-transaction) > > -> System transaction that supersedes `ChangeEpochTransaction` as the new way to run transactions -> at the end of an epoch. Behaves similarly to `ChangeEpochTransaction` but can accommodate other -> optional transactions to run at the end of the epoch. +> System transaction that supersedes `ChangeEpochTransaction` as the new way +> to run transactions at the end of an epoch. Behaves similarly to +> `ChangeEpochTransaction` but can accommodate other optional transactions to +> run at the end of the epoch. > diff --git a/docs/content/references/iota-api/iota-graphql/reference/types/unions/unchanged-shared-object.mdx b/docs/content/references/iota-api/iota-graphql/reference/types/unions/unchanged-shared-object.mdx index 05d9155728c..08cce7c806b 100644 --- a/docs/content/references/iota-api/iota-graphql/reference/types/unions/unchanged-shared-object.mdx +++ b/docs/content/references/iota-api/iota-graphql/reference/types/unions/unchanged-shared-object.mdx @@ -39,10 +39,10 @@ export const Details = ({ dataOpen, dataClose, children, startOpen = false }) => -Details pertaining to shared objects that are referenced by but not changed by a transaction. -This information is considered part of the effects, because although the transaction specifies -the shared object as input, consensus must schedule it and pick the version that is actually -used. +Details pertaining to shared objects that are referenced by but not changed +by a transaction. This information is considered part of the effects, +because although the transaction specifies the shared object as input, +consensus must schedule it and pick the version that is actually used. ```graphql @@ -63,8 +63,8 @@ union UnchangedSharedObject = SharedObjectRead | SharedObjectDelete #### [UnchangedSharedObject.SharedObjectDelete](/references/iota-api/iota-graphql/reference/types/objects/shared-object-delete) > > -> The transaction accepted a shared object as input, but it was deleted before the transaction -> executed. +> The transaction accepted a shared object as input, but it was deleted before +> the transaction executed. > diff --git a/docs/content/sidebars/about-iota.js b/docs/content/sidebars/about-iota.js index 9c4c1c6faf6..987107f8cc6 100644 --- a/docs/content/sidebars/about-iota.js +++ b/docs/content/sidebars/about-iota.js @@ -23,6 +23,15 @@ const aboutIota = [ 'about-iota/iota-architecture/staking-rewards', ], }, + { + type: 'category', + label: 'Execution Architecture', + items: [ + 'about-iota/execution-architecture/iota-execution', + 'about-iota/execution-architecture/adapter', + 'about-iota/execution-architecture/natives', + ], + }, { type: 'category', label: 'Tokenomics', diff --git a/docs/content/sidebars/concepts.js b/docs/content/sidebars/concepts.js deleted file mode 100644 index f4e53b8d018..00000000000 --- a/docs/content/sidebars/concepts.js +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright (c) Mysten Labs, Inc. -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -const concepts = [ - 'concepts', - 'concepts/components', - { - type: 'category', - label: 'App Developers', - link: { - type: 'doc', - id: 'concepts/app-devs', - }, - items: [ - 'concepts/graphql-rpc', - { - type: 'category', - label: 'Object Model', - link: { - type: 'doc', - id: 'concepts/object-model', - }, - items: [ - { - type: 'category', - label: 'Object Ownership', - link: { - type: 'doc', - id: 'concepts/object-ownership', - }, - items: [ - 'concepts/object-ownership/address-owned', - 'concepts/object-ownership/immutable', - 'concepts/object-ownership/shared', - 'concepts/object-ownership/wrapped', - ], - }, - { - type: 'category', - label: 'Dynamic Fields', - link: { - type: 'doc', - id: 'concepts/dynamic-fields', - }, - items: ['concepts/dynamic-fields/tables-bags'], - }, - { - type: 'category', - label: 'Transfers', - link: { - type: 'doc', - id: 'concepts/transfers', - }, - items: ['concepts/transfers/custom-rules', 'concepts/transfers/transfer-to-object'], - }, - 'concepts/events', - 'concepts/versioning', - ], - }, - { - type: 'category', - label: 'Move Overview', - link: { - type: 'doc', - id: 'concepts/iota-move-concepts', - }, - items: [ - 'concepts/iota-move-concepts/strings', - 'concepts/iota-move-concepts/collections', - 'concepts/iota-move-concepts/init', - 'concepts/iota-move-concepts/entry-functions', - 'concepts/iota-move-concepts/one-time-witness', - { - type: 'category', - label: 'Package Upgrades', - link: { - type: 'doc', - id: 'concepts/iota-move-concepts/packages', - }, - items: [ - 'concepts/iota-move-concepts/packages/upgrade', - 'concepts/iota-move-concepts/packages/custom-policies', - ], - }, - { - type: 'category', - label: 'Patterns', - link: { - type: 'doc', - id: 'concepts/iota-move-concepts/patterns', - }, - items: [ - 'concepts/iota-move-concepts/patterns/capabilities', - 'concepts/iota-move-concepts/patterns/witness', - 'concepts/iota-move-concepts/patterns/transferrable-witness', - 'concepts/iota-move-concepts/patterns/hot-potato', - 'concepts/iota-move-concepts/patterns/id-pointer', - 'concepts/iota-move-concepts/patterns/app-extensions', - ], - }, - 'concepts/iota-move-concepts/conventions', - ], - }, - { - type: 'category', - label: 'Transactions', - link: { - type: 'doc', - id: 'concepts/transactions', - }, - items: [ - 'concepts/transactions/prog-txn-blocks', - 'concepts/transactions/sponsored-transactions', - 'concepts/transactions/gas-smashing', - ], - }, - ], - }, - { - type: 'category', - label: 'Cryptography', - link: { - type: 'doc', - id: 'concepts/cryptography', - }, - items: [ - { - type: 'category', - label: 'Transaction Authentication', - link: { - type: 'doc', - id: 'concepts/cryptography/transaction-auth', - }, - items: [ - 'concepts/cryptography/transaction-auth/keys-addresses', - 'concepts/cryptography/transaction-auth/signatures', - 'concepts/cryptography/transaction-auth/multisig', - 'concepts/cryptography/transaction-auth/offline-signing', - 'concepts/cryptography/transaction-auth/intent-signing', - ], - }, - { - type: 'category', - label: 'zkLogin', - link: { - type: 'doc', - id: 'concepts/cryptography/zklogin', - }, - items: ['concepts/cryptography/zklogin/zklogin-example'], - }, - 'concepts/cryptography/system/checkpoint-verification', - /*{ - type: 'category', - label: 'System', - link: { - type: 'doc', - id: 'concepts/cryptography/system', - }, - items: [ - 'concepts/cryptography/system/validator-signatures', - 'concepts/cryptography/system/intents-for-validation', - 'concepts/cryptography/system/checkpoint-verification', - ], - },*/ - ], - }, - { - type: 'category', - label: 'IOTA Architecture', - link: { - type: 'doc', - id: 'concepts/iota-architecture', - }, - items: [ - 'concepts/iota-architecture/high-level', - 'concepts/iota-architecture/iota-security', - 'concepts/iota-architecture/transaction-lifecycle', - 'concepts/iota-architecture/consensus', - 'concepts/iota-architecture/indexer-functions', - 'concepts/iota-architecture/epochs', - 'concepts/iota-architecture/protocol-upgrades', - 'concepts/iota-architecture/data-management-things', - 'concepts/iota-architecture/staking-rewards', - ], - }, - { - type: 'category', - label: 'Tokenomics', - link: { - type: 'doc', - id: 'concepts/tokenomics', - }, - items: [ - 'concepts/tokenomics/proof-of-stake', - 'concepts/tokenomics/validators-staking', - 'concepts/tokenomics/staking-unstaking', - 'concepts/tokenomics/iota-coin', - 'concepts/tokenomics/iota-bridging', - 'concepts/tokenomics/storage-fund', - 'concepts/tokenomics/gas-pricing', - 'concepts/tokenomics/gas-in-iota', - ], - }, - { - type: 'category', - label: 'Execution Architecture', - items: [ - 'concepts/execution-architecture/iota-execution', - 'concepts/execution-architecture/adapter', - 'concepts/execution-architecture/natives', - ], - }, - 'concepts/research-papers', -]; -module.exports = concepts; diff --git a/docs/content/sidebars/developer.js b/docs/content/sidebars/developer.js index 22123c2d3f5..bc933bb386e 100644 --- a/docs/content/sidebars/developer.js +++ b/docs/content/sidebars/developer.js @@ -307,6 +307,7 @@ const developer = [ items: [ 'developer/standards/standards', 'developer/standards/coin', + 'developer/standards/coin-manager', { type: 'category', label: 'Closed-Loop Token', @@ -350,9 +351,29 @@ const developer = [ label: 'Integrate Your Exchange', items:[ 'developer/exchange-integration/exchange-integration', - 'developer/exchange-integration/stardust-migration', + + { + type: 'category', + label: 'Migrating IOTA/Shimmer Stardust', + link: { + type: 'doc', + id: 'developer/stardust/stardust-migration', + }, + items: [ + 'developer/stardust/exchanges', + 'developer/stardust/move-models', + 'developer/stardust/addresses', + 'developer/stardust/units', + 'developer/stardust/migration-process', + 'developer/stardust/claiming', + 'developer/stardust/vested', + 'developer/stardust/testing', + 'developer/stardust/if-tools', + 'developer/stardust/faq', + ], + }, ] - } + }, ] ; module.exports = developer; diff --git a/docs/content/sidebars/guides.js b/docs/content/sidebars/guides.js deleted file mode 100644 index 14fb31fd911..00000000000 --- a/docs/content/sidebars/guides.js +++ /dev/null @@ -1,234 +0,0 @@ -// Copyright (c) Mysten Labs, Inc. -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -const guides = [ - { - type: 'doc', - label: 'Guides', - id: 'guides', - }, - { - type: 'category', - label: 'Developer Guides', - collapsed: false, - link: { - type: 'doc', - id: 'guides/developer', - }, - items: [ - { - type: 'category', - label: 'Getting Started', - collapsed: false, - link: { - type: 'doc', - id: 'guides/developer/getting-started', - }, - items: [ - 'guides/developer/getting-started/iota-environment', - 'guides/developer/getting-started/iota-install', - 'guides/developer/getting-started/connect', - 'guides/developer/getting-started/local-network', - 'guides/developer/getting-started/get-address', - 'guides/developer/getting-started/get-coins', - 'guides/developer/getting-started/graphql-rpc', - ], - }, - { - type: 'category', - label: 'From Solidity/EVM to Move', - collapsed: true, - link: { - type: 'doc', - id: 'guides/developer/evm-to-move', - }, - items: [ - 'guides/developer/evm-to-move/why-move', - 'guides/developer/evm-to-move/tooling-apis', - 'guides/developer/evm-to-move/creating-token', - 'guides/developer/evm-to-move/creating-nft', - ], - }, - { - type: 'category', - label: 'Your First IOTA dApp', - link: { - type: 'doc', - id: 'guides/developer/first-app', - }, - items: [ - 'guides/developer/first-app/write-package', - 'guides/developer/first-app/build-test', - 'guides/developer/first-app/publish', - 'guides/developer/first-app/debug', - 'guides/developer/first-app/client-tssdk', - ], - }, - { - type: 'category', - label: 'IOTA 101', - link: { - type: 'doc', - id: 'guides/developer/iota-101', - }, - items: [ - 'guides/developer/iota-101/shared-owned', - { - type: 'category', - label: 'Create Coins and Tokens', - link: { - type: 'doc', - id: 'guides/developer/iota-101/create-coin', - }, - items: [ - 'guides/developer/iota-101/create-coin/regulated', - 'guides/developer/iota-101/create-coin/in-game-token', - 'guides/developer/iota-101/create-coin/loyalty', - ], - }, - 'guides/developer/iota-101/create-nft', - 'guides/developer/iota-101/using-events', - 'guides/developer/iota-101/access-time', - 'guides/developer/iota-101/sign-and-send-txn', - 'guides/developer/iota-101/sponsor-txn', - { - type: 'category', - label: 'Working with PTBs', - items: [ - 'guides/developer/iota-101/building-ptb', - 'guides/developer/iota-101/coin-mgt', - 'guides/developer/iota-101/simulating-refs', - ], - }, - ], - }, - { - type: 'category', - label: 'Cryptography', - link: { - type: 'doc', - id: 'guides/developer/cryptography', - }, - items: [ - 'guides/developer/cryptography/signing', - 'guides/developer/cryptography/groth16', - 'guides/developer/cryptography/hashing', - 'guides/developer/cryptography/ecvrf', - ], - }, - { - type: 'category', - label: 'Advanced Topics', - link: { - type: 'doc', - id: 'guides/developer/advanced', - }, - items: [ - /*{ - type: 'category', - label: 'Efficient Smart Contracts', - link: { - type: 'doc', - id: 'guides/developer/advanced/efficient-smart-contracts', - }, - items: ['guides/developer/advanced/min-gas-fees'], - },*/ - 'guides/developer/advanced/graphql-migration', - 'guides/developer/advanced/move-2024-migration', - 'guides/developer/advanced/asset-tokenization', - 'guides/developer/advanced/custom-indexer', - 'guides/developer/advanced/stardust-on-move', - ], - }, - { - type: 'category', - label: 'App Examples', - link: { - type: 'doc', - id: 'guides/developer/app-examples', - }, - items: [ - 'guides/developer/app-examples/auction', - 'guides/developer/app-examples/blackjack', - 'guides/developer/app-examples/coin-flip', - 'guides/developer/app-examples/e2e-counter', - { - type: 'category', - label: 'Oracles', - link: { - type: 'doc', - id: 'guides/developer/app-examples/oracle', - }, - items: [ - 'guides/developer/app-examples/weather-oracle', - 'guides/developer/app-examples/meta-pricing-oracle', - ], - }, - 'guides/developer/app-examples/plinko', - 'guides/developer/app-examples/recaptcha', - 'guides/developer/app-examples/tic-tac-toe', - { - type: 'category', - label: 'Trustless Token Swap', - link: { - type: 'doc', - id: 'guides/developer/app-examples/trustless-token-swap', - }, - items: [ - 'guides/developer/app-examples/trustless-token-swap/backend', - 'guides/developer/app-examples/trustless-token-swap/indexer-api', - 'guides/developer/app-examples/trustless-token-swap/frontend', - ], - }, - 'guides/developer/app-examples/trusted-swap', - 'guides/developer/app-examples/turnip-town', - ], - }, - 'guides/developer/starter-templates', - 'guides/developer/zklogin-onboarding', - 'guides/developer/dev-cheat-sheet', - ], - }, - { - type: 'category', - label: 'Operator Guides', - link: { - type: 'doc', - id: 'guides/operator', - }, - items: [ - 'guides/operator/iota-full-node', - 'guides/operator/validator-config', - 'guides/operator/data-management', - 'guides/operator/snapshots', - 'guides/operator/archives', - 'guides/operator/genesis', - 'guides/operator/validator-committee', - 'guides/operator/validator-tasks', - 'guides/operator/node-tools', - 'guides/operator/exchange-integration', - ], - }, - { - type: 'category', - label: 'Migrating IOTA/Shimmer Stardust', - link: { - type: 'doc', - id: 'guides/stardust-migration', - }, - items: [ - 'guides/stardust/move-models', - 'guides/stardust/addresses', - 'guides/stardust/units', - 'guides/stardust/migration-process', - 'guides/stardust/claiming', - 'guides/stardust/vested', - 'guides/stardust/testing', - 'guides/stardust/if-tools', - 'guides/stardust/exchanges', - 'guides/stardust/faq', - ], - }, -]; -module.exports = guides; diff --git a/docs/content/sidebars/standards.js b/docs/content/sidebars/standards.js deleted file mode 100644 index 69795456d0b..00000000000 --- a/docs/content/sidebars/standards.js +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) Mysten Labs, Inc. -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -const standards = [ - 'standards', - { - type: 'category', - label: 'Coin', - link: { - type: 'doc', - id: 'standards/coin', - }, - items: [ - 'standards/coin-manager', - ], - }, - { - type: 'category', - label: 'Closed-Loop Token', - link: { - type: 'doc', - id: 'standards/closed-loop-token', - }, - items: [ - 'standards/closed-loop-token/action-request', - 'standards/closed-loop-token/token-policy', - 'standards/closed-loop-token/spending', - 'standards/closed-loop-token/rules', - 'standards/closed-loop-token/coin-token-comparison', - ], - }, - 'standards/kiosk', - 'standards/kiosk-apps', - { - type: 'category', - label: 'DeepBook', - link: { - type: 'doc', - id: 'standards/deepbook', - }, - items: [ - 'standards/deepbook/design', - 'standards/deepbook/orders', - 'standards/deepbook/pools', - 'standards/deepbook/query-the-pool', - 'standards/deepbook/routing-a-swap', - 'standards/deepbook/trade-and-swap', - ], - }, - 'standards/display', - 'standards/wallet-standard', -]; -module.exports = standards; diff --git a/docs/site/docusaurus.config.js b/docs/site/docusaurus.config.js index c04be94896e..68d63be2795 100644 --- a/docs/site/docusaurus.config.js +++ b/docs/site/docusaurus.config.js @@ -173,6 +173,16 @@ const config = { autoCollapseCategories: false, }, }, + colorMode:{ + defaultMode: 'dark' + }, + announcementBar:{ + id: 'integrate_your_exchange', + content: + 'integrate your exchange. If you supported Stardust, please make sure to also migrate from Stardust.', + isCloseable: false, + + }, navbar: { title: "IOTA Documentation", logo: { @@ -196,11 +206,6 @@ const config = { label: "References", to: "references", }, - { - label: "Integrate Your Exchange", - to: "developer/exchange-integration/", - }, - /* { type: "docsVersionDropdown", From b1220e3ec6721051c75444f0ddee27941b45f7c8 Mon Sep 17 00:00:00 2001 From: Lucas Tortora Date: Mon, 8 Jul 2024 14:33:27 -0300 Subject: [PATCH 03/37] fix build --- .../{exchange-integration => stardust}/stardust-migration.mdx | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/content/developer/{exchange-integration => stardust}/stardust-migration.mdx (100%) diff --git a/docs/content/developer/exchange-integration/stardust-migration.mdx b/docs/content/developer/stardust/stardust-migration.mdx similarity index 100% rename from docs/content/developer/exchange-integration/stardust-migration.mdx rename to docs/content/developer/stardust/stardust-migration.mdx From 06d35ac4748e5c098a044b7ffaa82e5241f95330 Mon Sep 17 00:00:00 2001 From: Lucas Tortora Date: Tue, 9 Jul 2024 05:02:22 -0300 Subject: [PATCH 04/37] fix build --- docs/site/src/pages/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/site/src/pages/index.js b/docs/site/src/pages/index.js index 5bfd92abf11..2c22234d9f0 100644 --- a/docs/site/src/pages/index.js +++ b/docs/site/src/pages/index.js @@ -66,7 +66,7 @@ export default function Home() { explanations/ Get started From f2643cee4eed578d8dfea9f9abfd364825f37e71 Mon Sep 17 00:00:00 2001 From: Lucas Tortora Date: Wed, 10 Jul 2024 12:33:01 -0300 Subject: [PATCH 05/37] update sidebars after merge from develop fix links --- .../developer/stardust/move-models.mdx | 20 +- .../developer/stardust/stardust-migration.mdx | 10 +- docs/content/sidebars/developer.js | 1 + docs/content/sidebars/guides.js | 234 ------------------ 4 files changed, 16 insertions(+), 249 deletions(-) delete mode 100644 docs/content/sidebars/guides.js diff --git a/docs/content/developer/stardust/move-models.mdx b/docs/content/developer/stardust/move-models.mdx index 6515466b260..f269b6a7853 100644 --- a/docs/content/developer/stardust/move-models.mdx +++ b/docs/content/developer/stardust/move-models.mdx @@ -40,7 +40,7 @@ genesis of the network. - [`timelock_unlock_condition`](../../references/framework/stardust/timelock_unlock_condition.md): Defines how a timelock unlock condition is modeled. - [`irc27`](../../references/framework/stardust/irc27.md): Defines how an IRC-27 metadata is modeled. - [`utilities`](../../references/framework/stardust/utilities.md): Contains utility functions for the stardust package, primarily to help with extracting assets from containers. - - There is no dedicated module for foundries and native tokens, since they are converted to [move-native tokens](../developer/evm-to-move/creating-token.mdx) + - There is no dedicated module for foundries and native tokens, since they are converted to [move-native tokens](../evm-to-move/creating-token.mdx) along with the base tokens (IOTA/SMR). These models are already part of the [`iota-framework`](../../references/framework/iota-framework). There is intentionally no constructor for any of the object types defined in the Stardust package, since they can @@ -122,7 +122,7 @@ to hold balances of tokens, as well as the [`CoinManager`](../../references/fram to control the supply of the token through minting and burning. A native token and its foundry from the Stardust ledger therefore translate to the following in the move ledger: - - A published move package that defines the currency type ([one-time witness](../../concepts/iota-move-concepts/one-time-witness.mdx)) + - A published move package that defines the currency type ([one-time witness](../iota-101/iota-move-concepts/one-time-witness.mdx)) for the native token. The template that is used for every native token package can be found in the [IOTA Genesis Builder](https://github.com/iotaledger/iota/blob/develop/crates/iota-genesis-builder/src/stardust/native_token/package_template/sources/native_token_template.move). The parameters of the template are filled with the [IRC-30 metadata](https://github.com/iotaledger/tips/blob/main/tips/TIP-0030/tip-0030.md) of the native token from Stardust. - The `CoinManager` shared object that gives access to the coin metadata and supply on-chain. @@ -151,7 +151,7 @@ A more detailed description on the process can be found in [Advanced Topics](./a The unique `AliasID` of the Stardust asset is persisted as the `ObjectID` of the migrated `Alias` object. All assets and outputs that were owned by the `Alias Address` in Stardust are now owned by the `Alias` object in move. There is a special [receiving -functionality in the new move framework](../../concepts/transfers/transfer-to-object.mdx#receiving-objects) that +functionality in the new move framework](../iota-101/objects/transfers/transfer-to-object.mdx#receiving-objects) that allows one to receive assets on the an `ObjectID` that is an `AliasID`. The following functions let an `Alias` receive other Stardust containers: - [`unlock_alias_address_owned_basic`](../../references/framework/stardust/address_unlock_condition.md#function-unlock_alias_address_owned_basic) @@ -163,7 +163,7 @@ functionality in the new move framework](../../concepts/transfers/transfer-to-ob NFTs are migrated very similarly to aliases. The NFT object in move is called [`Nft`](../../references/framework/stardust/nft.md#resource-nft). The unique `NftID` of the Stardust asset is persisted as the `ObjectID` of the migrated `Nft` object. All assets and outputs that were owned by the `Nft Address` in Stardust are now owned by the `Nft` object in move. There is a special [receiving -functionality in the new move framework](../../concepts/transfers/transfer-to-object.mdx#receiving-objects) that +functionality in the new move framework](../iota-101/objects/transfers/transfer-to-object.mdx#receiving-objects) that allows one to receive assets on the an `ObjectID` that is an `NftID`. The following functions let an `Nft` receive other Stardust containers: - [`unlock_nft_address_owned_basic`](../../references/framework/stardust/address_unlock_condition.md#function-unlock_nft_address_owned_basic) @@ -181,7 +181,7 @@ Once that happens, they are destroyed. The containers are: - [`NftOutput`](../../references/framework/stardust/nft_output#resource-nftoutput): Represents an NFT output container. On move level, all of them are defined with only a `key` type ability, which means that they only support [custom transfer -rules](../../concepts/transfers/custom-rules.mdx). The only way to interact with the containers is to call `extract_assets()` +rules](../iota-101/objects/transfers/custom-rules.mdx). The only way to interact with the containers is to call `extract_assets()` move function on them, which will return the assets they hold and destroy the container. During the `extract_assets()` call, the legacy unlock conditions are checked, that is, the claiming transaction will fail @@ -192,7 +192,7 @@ if they are not respected. This is required to not change semantically the rules The most common unlock condition (which is mandatory for most outputs) in legacy Stardust is the [`Address Unlock Condition`](https://github.com/iotaledger/tips/blob/main/tips/TIP-0018/tip-0018.md#address-unlock-condition). It simply locks the output behind an address, therefore, in move it is represented as a simple [address ownership of the -object](../../concepts/object-ownership/address-owned.mdx). +object](../iota-101/objects/object-ownership/address-owned.mdx). - All migrated objects, except the ones with Expiration Unlock Condition, become owned objects in the move ledger. - The address that owns the object is the address that was in the `Address Unlock Condition` of the Stardust output. - Move addresses are 32 bytes, which is the same length as the legacy addresses in Stardust without the type byte. @@ -247,7 +247,7 @@ which checks if the expiration time has passed and if so, transfers the ownershi :::info Since the conditional ownership can only be modeled in on-chain move code, outputs from Stardust with expiration unlock conditions are -migrated to [Shared Objects](../../concepts/object-ownership/shared.mdx). As opposed to owned objects, shared objects +migrated to [Shared Objects](../iota-101/objects/object-ownership/shared.mdx). As opposed to owned objects, shared objects can be touched by anyone, however the move level code ensures that only the rightful owner can claim the assets. ::: @@ -349,7 +349,7 @@ There are two ways to interact with `BasicOutputs` in move: of the base token balance and from the native token balances extracted from the `Bag`. The [Claiming Stardust Assets](./claiming.mdx) guide explains in detail what is the recommended way to deal with these results. -2. Receive them on an `ObjectID` address. The [Receiving Objects](../../concepts/transfers/transfer-to-object.mdx#receiving-objects) +2. Receive them on an `ObjectID` address. The [Receiving Objects](../iota-101/objects/transfers/transfer-to-object.mdx#receiving-objects) guide explains how to receive assets on an object. In the Stardust models the following two functions are used to receive `BasicOutputs` that were locked in the legacy network to `Alias` or `Nft` addresses: - [`unlock_alias_address_owned_basic()`](../../references/framework/stardust/address_unlock_condition.md#function-unlock_alias_address_owned_basic) @@ -364,7 +364,7 @@ following assets: - Base token balance (IOTA/SMR) of the migrated Stardust output, - A `Bag` that holds native tokens of the migrated Stardust output, and - The [`Alias`](../../references/framework/stardust/alias#resource-alias) object that represents the alias in the move ledger. - While this latter asset is not part of the container as a field, it is added to it as a [`dynamic object field`](../../concepts/dynamic-fields) + While this latter asset is not part of the container as a field, it is added to it as a [`dynamic object field`](../iota-101/objects/dynamic-fields/dynamic-fields.mdx) during the migration process. This has the added benefit that the previous `AliasID` of the Stardust output is preserved as the `ObjectID` of the `Alias` object, and can be directly queried from the node API/indexer. During the claiming process, the `extract_assets()` function automatically loads the `Alias`, removes it as a dynamic field from the container and returns it. @@ -441,7 +441,7 @@ The [`NftOutput`](../../references/framework/stardust/nft_output#resource-nftout - Base token balance (IOTA/SMR) of the migrated Stardust output, - A `Bag` that holds native tokens of the migrated Stardust output, and - The [`Nft`](../../references/framework/stardust/nft#resource-nft) object that represents the NFT in the move ledger. - While this latter asset is not part of the container as a field, it is added to it as a [`dynamic object field`](../../concepts/dynamic-fields) + While this latter asset is not part of the container as a field, it is added to it as a [`dynamic object field`](../iota-101/objects/dynamic-fields/dynamic-fields.mdx) during the migration process. This has the added benefit that the previous `NftID` of the Stardust output is preserved as the `ObjectID` of the `Nft` object, and can be directly queried from the node API/indexer. During the claiming process, the `extract_assets()` function automatically loads the `Nft`, removes it as a dynamic field from the container and returns it. diff --git a/docs/content/developer/stardust/stardust-migration.mdx b/docs/content/developer/stardust/stardust-migration.mdx index 637edac1e0a..14bf3415796 100644 --- a/docs/content/developer/stardust/stardust-migration.mdx +++ b/docs/content/developer/stardust/stardust-migration.mdx @@ -1,6 +1,6 @@ --- - title: Stardust Migration - description: Describes the migration from IOTA Stardust to the IOTA Move-based ledger. +title: Stardust Migration +description: Describes the migration from IOTA Stardust to the IOTA Move-based ledger. --- The (legacy) IOTA and Shimmer networks run the Stardust protocol version that represents assets and tokens in a UTXO-based ledger. @@ -16,7 +16,7 @@ The Stardust ledger state, and hence the assets and tokens in the network, are r Transactions consume previously unspent outputs, essentially removing them from the ledger, and create new outputs, thus updating the ledger state. With the introduction of the object-based Move ledger in IOTA Rebased, transactions no longer consume and create outputs, -but [`Move Objects`](../concepts/object-model.mdx) instead. A move transaction names `input objects` that it intends to operate on (consume), and executing +but [`Move Objects`](../iota-101/objects/object-model.mdx) instead. A move transaction names `input objects` that it intends to operate on (consume), and executing the transaction produces the set of new objects to be written into the ledger, while the `input objects` are removed. The two models are conceptually really similar, but the underlying data structures are different, since move objects can @@ -58,7 +58,7 @@ All previous IOTA and Shimmer integrations are broken and have to be reimplement need to migrate secrets.** While the Ed25519 address scheme stays the same, address representation changes from Bech32 to Base58 hex encoding with - a `0x` prefix. The [Addresses and Keys](./stardust/addresses.mdx) guide provides help on how to acquire how to parse Bech32 addresses to the new format. + a `0x` prefix. The [Addresses and Keys](./addresses.mdx) guide provides help on how to acquire how to parse Bech32 addresses to the new format. ## How Can I Access Migrated Assets? @@ -67,7 +67,7 @@ find their assets on the IOTA Rebased network. Should it be necessary based on t that talks to the browser extension wallet helps users to claim their assets. Developers can use the official SDKs and APIs to claim assets programmatically based on the information provided on the -following pages. Example transactions on how to claim are described in the [Claiming Stardust Assets](./stardust/claiming.mdx) guide. +following pages. Example transactions on how to claim are described in the [Claiming Stardust Assets](./claiming.mdx) guide. ## What Tools Can I Use? diff --git a/docs/content/sidebars/developer.js b/docs/content/sidebars/developer.js index bc933bb386e..3fdb4cd2252 100644 --- a/docs/content/sidebars/developer.js +++ b/docs/content/sidebars/developer.js @@ -370,6 +370,7 @@ const developer = [ 'developer/stardust/testing', 'developer/stardust/if-tools', 'developer/stardust/faq', + 'developer/stardust/advanced', ], }, ] diff --git a/docs/content/sidebars/guides.js b/docs/content/sidebars/guides.js deleted file mode 100644 index b0d1d8665d7..00000000000 --- a/docs/content/sidebars/guides.js +++ /dev/null @@ -1,234 +0,0 @@ -// Copyright (c) Mysten Labs, Inc. -// Modifications Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -const guides = [ - { - type: 'doc', - label: 'Guides', - id: 'guides', - }, - { - type: 'category', - label: 'Developer Guides', - collapsed: false, - link: { - type: 'doc', - id: 'guides/developer', - }, - items: [ - { - type: 'category', - label: 'Getting Started', - collapsed: false, - link: { - type: 'doc', - id: 'guides/developer/getting-started', - }, - items: [ - 'guides/developer/getting-started/iota-environment', - 'guides/developer/getting-started/iota-install', - 'guides/developer/getting-started/connect', - 'guides/developer/getting-started/local-network', - 'guides/developer/getting-started/get-address', - 'guides/developer/getting-started/get-coins', - 'guides/developer/getting-started/graphql-rpc', - ], - }, - { - type: 'category', - label: 'From Solidity/EVM to Move', - collapsed: true, - link: { - type: 'doc', - id: 'guides/developer/evm-to-move', - }, - items: [ - 'guides/developer/evm-to-move/why-move', - 'guides/developer/evm-to-move/tooling-apis', - 'guides/developer/evm-to-move/creating-token', - 'guides/developer/evm-to-move/creating-nft', - ], - }, - { - type: 'category', - label: 'Your First IOTA dApp', - link: { - type: 'doc', - id: 'guides/developer/first-app', - }, - items: [ - 'guides/developer/first-app/write-package', - 'guides/developer/first-app/build-test', - 'guides/developer/first-app/publish', - 'guides/developer/first-app/debug', - 'guides/developer/first-app/client-tssdk', - ], - }, - { - type: 'category', - label: 'IOTA 101', - link: { - type: 'doc', - id: 'guides/developer/iota-101', - }, - items: [ - 'guides/developer/iota-101/shared-owned', - { - type: 'category', - label: 'Create Coins and Tokens', - link: { - type: 'doc', - id: 'guides/developer/iota-101/create-coin', - }, - items: [ - 'guides/developer/iota-101/create-coin/regulated', - 'guides/developer/iota-101/create-coin/in-game-token', - 'guides/developer/iota-101/create-coin/loyalty', - ], - }, - 'guides/developer/iota-101/create-nft', - 'guides/developer/iota-101/using-events', - 'guides/developer/iota-101/access-time', - 'guides/developer/iota-101/sign-and-send-txn', - 'guides/developer/iota-101/sponsor-txn', - { - type: 'category', - label: 'Working with PTBs', - items: [ - 'guides/developer/iota-101/building-ptb', - 'guides/developer/iota-101/coin-mgt', - 'guides/developer/iota-101/simulating-refs', - ], - }, - ], - }, - { - type: 'category', - label: 'Cryptography', - link: { - type: 'doc', - id: 'guides/developer/cryptography', - }, - items: [ - 'guides/developer/cryptography/signing', - 'guides/developer/cryptography/groth16', - 'guides/developer/cryptography/hashing', - 'guides/developer/cryptography/ecvrf', - ], - }, - { - type: 'category', - label: 'Advanced Topics', - link: { - type: 'doc', - id: 'guides/developer/advanced', - }, - items: [ - /*{ - type: 'category', - label: 'Efficient Smart Contracts', - link: { - type: 'doc', - id: 'guides/developer/advanced/efficient-smart-contracts', - }, - items: ['guides/developer/advanced/min-gas-fees'], - },*/ - 'guides/developer/advanced/graphql-migration', - 'guides/developer/advanced/move-2024-migration', - 'guides/developer/advanced/asset-tokenization', - 'guides/developer/advanced/custom-indexer', - ], - }, - { - type: 'category', - label: 'App Examples', - link: { - type: 'doc', - id: 'guides/developer/app-examples', - }, - items: [ - 'guides/developer/app-examples/auction', - 'guides/developer/app-examples/blackjack', - 'guides/developer/app-examples/coin-flip', - 'guides/developer/app-examples/e2e-counter', - { - type: 'category', - label: 'Oracles', - link: { - type: 'doc', - id: 'guides/developer/app-examples/oracle', - }, - items: [ - 'guides/developer/app-examples/weather-oracle', - 'guides/developer/app-examples/meta-pricing-oracle', - ], - }, - 'guides/developer/app-examples/plinko', - 'guides/developer/app-examples/recaptcha', - 'guides/developer/app-examples/tic-tac-toe', - { - type: 'category', - label: 'Trustless Token Swap', - link: { - type: 'doc', - id: 'guides/developer/app-examples/trustless-token-swap', - }, - items: [ - 'guides/developer/app-examples/trustless-token-swap/backend', - 'guides/developer/app-examples/trustless-token-swap/indexer-api', - 'guides/developer/app-examples/trustless-token-swap/frontend', - ], - }, - 'guides/developer/app-examples/trusted-swap', - 'guides/developer/app-examples/turnip-town', - ], - }, - 'guides/developer/starter-templates', - 'guides/developer/zklogin-onboarding', - 'guides/developer/dev-cheat-sheet', - ], - }, - { - type: 'category', - label: 'Operator Guides', - link: { - type: 'doc', - id: 'guides/operator', - }, - items: [ - 'guides/operator/iota-full-node', - 'guides/operator/validator-config', - 'guides/operator/data-management', - 'guides/operator/snapshots', - 'guides/operator/archives', - 'guides/operator/genesis', - 'guides/operator/validator-committee', - 'guides/operator/validator-tasks', - 'guides/operator/node-tools', - 'guides/operator/exchange-integration', - ], - }, - { - type: 'category', - label: 'Migrating IOTA/Shimmer Stardust', - link: { - type: 'doc', - id: 'guides/stardust-migration', - }, - items: [ - 'guides/stardust/move-models', - 'guides/stardust/addresses', - 'guides/stardust/units', - 'guides/stardust/migration-process', - 'guides/stardust/claiming', - 'guides/stardust/vested', - 'guides/stardust/testing', - 'guides/stardust/if-tools', - 'guides/stardust/exchanges', - 'guides/stardust/faq', - 'guides/stardust/advanced', - ], - }, -]; -module.exports = guides; From 84874fb23108968d5dce968c5a2a2cede873db3b Mon Sep 17 00:00:00 2001 From: Lucas Tortora <85233773+lucas-tortora@users.noreply.github.com> Date: Fri, 12 Jul 2024 08:04:27 -0300 Subject: [PATCH 06/37] Update docs/site/docusaurus.config.js Co-authored-by: Jeroen van den Hout --- docs/site/docusaurus.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/site/docusaurus.config.js b/docs/site/docusaurus.config.js index cafbc999e7d..5d2174cca79 100644 --- a/docs/site/docusaurus.config.js +++ b/docs/site/docusaurus.config.js @@ -179,7 +179,7 @@ const config = { announcementBar:{ id: 'integrate_your_exchange', content: - 'integrate your exchange. If you supported Stardust, please make sure to also migrate from Stardust.', + 'Integrate your exchange. If you supported Stardust, please make sure to also migrate from Stardust.', isCloseable: false, }, From 672b6f9529baa53c048787e20b7adf1c3830bd5e Mon Sep 17 00:00:00 2001 From: Lucas Tortora Date: Fri, 12 Jul 2024 08:16:00 -0300 Subject: [PATCH 07/37] fix: update anouncemet bar colours --- docs/site/docusaurus.config.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/site/docusaurus.config.js b/docs/site/docusaurus.config.js index 5d2174cca79..1242bcea1bb 100644 --- a/docs/site/docusaurus.config.js +++ b/docs/site/docusaurus.config.js @@ -181,6 +181,8 @@ const config = { content: 'Integrate your exchange. If you supported Stardust, please make sure to also migrate from Stardust.', isCloseable: false, + backgroundColor: '#0101ff', + textColor: '#FFFFFF', }, navbar: { From 59f3e146df4b35036995decb5907defb7a3daa84 Mon Sep 17 00:00:00 2001 From: Jeroen van den Hout Date: Sun, 9 Jun 2024 23:52:03 +0200 Subject: [PATCH 08/37] feat(docs): add ISC docs --- .../_EVM-required-prior-knowledge.md | 14 + .../_admonitions/_EVM_compatibility.md | 7 + .../_admonitions/_about-accounts.md | 5 + .../_admonitions/_deploy_a_smart_contract.md | 5 + .../_admonitions/_ownership.md | 7 + .../_admonitions/_payable.md | 10 + .../_admonitions/_remix-IDE.md | 6 + .../_partials/_hardhat_config.mdx | 67 + .../_partials/_on_off_ledger_request.md | 13 + .../how-tos/token/_check_storage_deposit.md | 10 + .../how-tos/token/_example_code_intro.mdx | 9 + .../how-tos/token/_obsolete_token_creation.md | 5 + .../explanations/consensus.md | 53 + .../explanations/context.mdx | 50 + .../explanations/core-contracts.md | 37 + .../explanations/how-accounts-work.md | 102 ++ .../explanations/invocation.md | 108 ++ .../explanations/sandbox.md | 45 + .../explanations/smart-contract-anatomy.md | 77 ++ .../explanations/smart-contracts.md | 54 + .../explanations/state_manager.md | 209 +++ .../explanations/states.md | 122 ++ .../explanations/validators.md | 49 + .../getting-started/compatibility.md | 46 + .../getting-started/languages-and-vms.md | 84 ++ .../getting-started/networks-and-chains.mdx | 143 ++ .../getting-started/quick-start.mdx | 83 ++ .../getting-started/tools.mdx | 189 +++ .../layer-2-smart-contracts/how-tos/ERC20.md | 94 ++ .../layer-2-smart-contracts/how-tos/ERC721.md | 129 ++ .../core-contracts/basics/allowance/allow.md | 64 + .../basics/allowance/get-allowance.md | 79 ++ .../basics/allowance/take-allowance.md | 56 + .../core-contracts/basics/get-balance.md | 74 ++ .../basics/send-assets-to-l1.mdx | 70 + .../how-tos/core-contracts/call-view.md | 96 ++ .../core-contracts/get-randomness-on-l2.md | 127 ++ .../how-tos/core-contracts/introduction.md | 79 ++ .../core-contracts/nft/introduction.md | 17 + .../how-tos/core-contracts/nft/mint-nft.md | 152 +++ .../core-contracts/nft/use-as-erc721.md | 33 + .../core-contracts/token/create-foundry.md | 71 + .../token/create-native-token.md | 91 ++ .../token/erc20-native-token.md | 45 + .../core-contracts/token/introduction.md | 18 + .../core-contracts/token/mint-token.md | 41 + .../core-contracts/token/register-token.md | 56 + .../how-tos/create-a-basic-contract.md | 53 + .../how-tos/deploy-a-smart-contract.mdx | 196 +++ .../how-tos/introduction.md | 29 + .../how-tos/send-ERC20-across-chains.md | 297 +++++ .../how-tos/send-NFTs-across-chains.md | 365 ++++++ .../how-tos/send-funds-from-L1-to-L2.mdx | 102 ++ .../how-tos/test-smart-contracts.md | 108 ++ .../layer-2-smart-contracts/introduction.md | 74 ++ .../schema/how-tos/access.mdx | 37 + .../schema/how-tos/call.mdx | 178 +++ .../schema/how-tos/events.mdx | 317 +++++ .../schema/how-tos/funcdesc.mdx | 404 ++++++ .../schema/how-tos/funcs.mdx | 82 ++ .../schema/how-tos/init.mdx | 269 ++++ .../schema/how-tos/params.mdx | 102 ++ .../schema/how-tos/post.mdx | 99 ++ .../schema/how-tos/results.mdx | 85 ++ .../schema/how-tos/spec.mdx | 460 +++++++ .../schema/how-tos/state.mdx | 187 +++ .../schema/how-tos/structs.mdx | 513 ++++++++ .../schema/how-tos/thunks.mdx | 379 ++++++ .../schema/how-tos/transfers.mdx | 242 ++++ .../schema/how-tos/typedefs.mdx | 456 +++++++ .../schema/how-tos/usage.mdx | 302 +++++ .../schema/how-tos/views.mdx | 133 ++ .../schema/how-tos/yaml.mdx | 69 + .../schema/introduction.mdx | 62 + .../schema/proxies.mdx | 76 ++ .../solo/getting-started.md | 80 ++ .../solo/how-tos/deploying-sc.md | 70 + .../solo/how-tos/error-handling.md | 51 + .../solo/how-tos/examples.mdx | 282 ++++ .../solo/how-tos/first-example.md | 94 ++ .../solo/how-tos/invoking-sc.md | 116 ++ .../solo/how-tos/test.mdx | 123 ++ .../solo/how-tos/the-l1-ledger.md | 71 + .../solo/how-tos/the-l2-ledger.md | 176 +++ .../solo/how-tos/timelock.mdx | 131 ++ .../solo/how-tos/view-sc.md | 74 ++ .../how-tos/chain-management.md | 74 ++ .../how-tos/running-a-node.md | 34 + .../how-tos/running-an-access-node.md | 283 ++++ .../how-tos/setting-up-a-chain.md | 176 +++ .../how-tos/wasp-cli.md | 67 + .../reference/configuration.md | 573 ++++++++ .../reference/metrics.md | 22 + .../layer-2-smart-contracts/.gitignore | 3 + .../core-contracts/accounts.md | 393 ++++++ .../core-contracts/blob.md | 108 ++ .../core-contracts/blocklog.md | 202 +++ .../core-contracts/errors.md | 77 ++ .../core-contracts/evm.md | 170 +++ .../core-contracts/governance.md | 355 +++++ .../core-contracts/overview.md | 37 + .../core-contracts/root.md | 121 ++ .../core-contracts/xfer.md | 71 + .../layer-2-smart-contracts/json-rpc-spec.md | 68 + .../magic-contract/introduction.md | 38 + .../wasm-lib-data-types.mdx | 104 ++ docs/content/sidebars/developer.js | 1154 +++++++++++------ docs/content/sidebars/operator.js | 57 +- docs/content/sidebars/references.js | 78 ++ 109 files changed, 13844 insertions(+), 366 deletions(-) create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_EVM-required-prior-knowledge.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_EVM_compatibility.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_about-accounts.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_deploy_a_smart_contract.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_ownership.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_payable.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_remix-IDE.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/_partials/_hardhat_config.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/_partials/_on_off_ledger_request.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/_partials/how-tos/token/_check_storage_deposit.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/_partials/how-tos/token/_example_code_intro.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/_partials/how-tos/token/_obsolete_token_creation.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/explanations/consensus.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/explanations/context.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/explanations/core-contracts.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/explanations/how-accounts-work.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/explanations/invocation.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/explanations/sandbox.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/explanations/smart-contract-anatomy.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/explanations/smart-contracts.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/explanations/state_manager.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/explanations/states.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/explanations/validators.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/getting-started/compatibility.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/getting-started/languages-and-vms.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/getting-started/networks-and-chains.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/getting-started/quick-start.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/getting-started/tools.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/ERC20.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/ERC721.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/allow.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/get-allowance.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/take-allowance.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/get-balance.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/send-assets-to-l1.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/call-view.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/get-randomness-on-l2.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/introduction.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/introduction.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/mint-nft.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/use-as-erc721.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/create-foundry.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/create-native-token.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/erc20-native-token.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/introduction.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/mint-token.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/register-token.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/create-a-basic-contract.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/deploy-a-smart-contract.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/introduction.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/send-ERC20-across-chains.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/send-NFTs-across-chains.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/send-funds-from-L1-to-L2.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/how-tos/test-smart-contracts.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/introduction.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/access.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/call.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/events.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/funcdesc.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/funcs.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/init.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/params.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/post.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/results.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/spec.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/state.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/structs.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/thunks.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/transfers.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/typedefs.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/usage.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/views.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/yaml.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/schema/introduction.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/schema/proxies.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/solo/getting-started.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/deploying-sc.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/error-handling.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/examples.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/first-example.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/invoking-sc.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/test.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/the-l1-ledger.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/the-l2-ledger.md create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/timelock.mdx create mode 100644 docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/view-sc.md create mode 100644 docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/chain-management.md create mode 100644 docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/running-a-node.md create mode 100644 docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/running-an-access-node.md create mode 100644 docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/setting-up-a-chain.md create mode 100644 docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/wasp-cli.md create mode 100755 docs/content/guides/operator/layer-2-smart-contracts-node/reference/configuration.md create mode 100644 docs/content/guides/operator/layer-2-smart-contracts-node/reference/metrics.md create mode 100644 docs/content/references/layer-2-smart-contracts/.gitignore create mode 100644 docs/content/references/layer-2-smart-contracts/core-contracts/accounts.md create mode 100644 docs/content/references/layer-2-smart-contracts/core-contracts/blob.md create mode 100644 docs/content/references/layer-2-smart-contracts/core-contracts/blocklog.md create mode 100644 docs/content/references/layer-2-smart-contracts/core-contracts/errors.md create mode 100644 docs/content/references/layer-2-smart-contracts/core-contracts/evm.md create mode 100644 docs/content/references/layer-2-smart-contracts/core-contracts/governance.md create mode 100644 docs/content/references/layer-2-smart-contracts/core-contracts/overview.md create mode 100644 docs/content/references/layer-2-smart-contracts/core-contracts/root.md create mode 100644 docs/content/references/layer-2-smart-contracts/core-contracts/xfer.md create mode 100644 docs/content/references/layer-2-smart-contracts/json-rpc-spec.md create mode 100644 docs/content/references/layer-2-smart-contracts/magic-contract/introduction.md create mode 100644 docs/content/references/layer-2-smart-contracts/wasm-lib-data-types.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_EVM-required-prior-knowledge.md b/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_EVM-required-prior-knowledge.md new file mode 100644 index 00000000000..c1e17089a98 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_EVM-required-prior-knowledge.md @@ -0,0 +1,14 @@ +:::note Required Prior Knowledge + +This guide assumes you are familiar with the concept +of [tokens](https://en.wikipedia.org/wiki/Cryptocurrency#Crypto_token) +in [blockchain](https://en.wikipedia.org/wiki/Blockchain), +[Ethereum Request for Comments (ERCs)](https://eips.ethereum.org/erc)(also known as Ethereum Improvement Proposals ( +EIP)) +, [NFTs](/learn/protocols/stardust/core-concepts/multi-asset-ledger#non-fungible-tokens-nfts), [Smart Contracts](/learn/smart-contracts/introduction) +and have already tinkered with [Solidity](https://docs.soliditylang.org/en/v0.8.16/). + +You should also have basic knowledge on how to [create](../how-tos/create-a-basic-contract.md) and [deploy](../how-tos/deploy-a-smart-contract.mdx) +a smart contract. + +::: \ No newline at end of file diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_EVM_compatibility.md b/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_EVM_compatibility.md new file mode 100644 index 00000000000..1f20154e1ea --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_EVM_compatibility.md @@ -0,0 +1,7 @@ +:::info EVM Compatibility + +The ISC EVM layer is also designed to be as compatible as possible with existing Ethereum +[tools](../getting-started/tools.mdx) and functionalities. However, please make sure you have checked out the current +[properties and limitations](../getting-started/compatibility.md). + +::: \ No newline at end of file diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_about-accounts.md b/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_about-accounts.md new file mode 100644 index 00000000000..4095981384d --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_about-accounts.md @@ -0,0 +1,5 @@ +:::info Accounts in ISC + +Learn more about the [different types of accounts](../explanations/how-accounts-work.md). + +::: \ No newline at end of file diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_deploy_a_smart_contract.md b/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_deploy_a_smart_contract.md new file mode 100644 index 00000000000..de4579b6d81 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_deploy_a_smart_contract.md @@ -0,0 +1,5 @@ +:::tip Deploy a Smart Contract + +Deploy a Solidity Smart Contract following our [how to Deploy a Smart Contract guide](/isc/how-tos/deploy-a-smart-contract#remix). + +::: diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_ownership.md b/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_ownership.md new file mode 100644 index 00000000000..fa86ee2f72f --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_ownership.md @@ -0,0 +1,7 @@ +:::info Ownership + +You might want to look into making the function ownable with, for example, +[OpenZeppelin](https://docs.openzeppelin.com/contracts/5.x/access-control#ownership-and-ownable) +so only owners of the contract can call certain functionalities of your contract. + +::: \ No newline at end of file diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_payable.md b/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_payable.md new file mode 100644 index 00000000000..2975d1d26d4 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_payable.md @@ -0,0 +1,10 @@ +:::info Payable + +Instead of making the function payable, you could let the contract pay for the storage deposit. +If so, you will need to change the `require` statement to check if the contract's balance has enough funds: + +```solidity +require(address(this).balance > _storageDeposit); +``` + +::: \ No newline at end of file diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_remix-IDE.md b/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_remix-IDE.md new file mode 100644 index 00000000000..5cfa57d5e69 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_remix-IDE.md @@ -0,0 +1,6 @@ +:::tip Remix + +This guide will use the [Remix IDE](https://remix.ethereum.org/), but you can use this contract with any IDE you are +familiar with. + +::: \ No newline at end of file diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_partials/_hardhat_config.mdx b/docs/content/guides/developer/layer-2-smart-contracts/_partials/_hardhat_config.mdx new file mode 100644 index 00000000000..96b134330bb --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/_partials/_hardhat_config.mdx @@ -0,0 +1,67 @@ +import CodeBlock from '@theme/CodeBlock'; +import { Networks } from '@theme/constant'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + + + + +{` +networks: { + 'iotaevm-testnet': { + url: '${Networks['iota_testnet'].evm.rpcUrls[0]}', + chainId: ${parseInt(Networks['iota_testnet'].evm.chainId)}, + accounts: [YOUR PRIVATE KEY], + }, +} +`} + + + + + + +{` +networks: { + 'shimmerevm-testnet': { + url: '${Networks['shimmer_testnet'].evm.rpcUrls[0]}', + chainId: ${parseInt(Networks['shimmer_testnet'].evm.chainId)}, + accounts: [YOUR PRIVATE KEY], + }, +} +`} + + + + + + +{` +networks: { + 'iotaevm': { + url: '${Networks['iota'].evm.rpcUrls[0]}', + chainId: ${parseInt(Networks['iota'].evm.chainId)}, + accounts: [YOUR PRIVATE KEY], + }, +} +`} + + + + + + +{` +networks: { + 'shimmerevm': { + url: '${Networks['shimmer'].evm.rpcUrls[0]}', + chainId: ${parseInt(Networks['shimmer'].evm.chainId)}, + accounts: [YOUR PRIVATE KEY], + }, +} +`} + + + + \ No newline at end of file diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_partials/_on_off_ledger_request.md b/docs/content/guides/developer/layer-2-smart-contracts/_partials/_on_off_ledger_request.md new file mode 100644 index 00000000000..45d59c458c3 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/_partials/_on_off_ledger_request.md @@ -0,0 +1,13 @@ +### On-Ledger Requests + +An on-ledger request is a Layer 1 transaction that validator nodes retrieve from the Tangle. The Tangle acts as an +arbiter between users and chains and guarantees that the transaction is valid, making it the only way to transfer assets +to a chain or between chains. + +### Off-Ledger Requests + +If all necessary assets are in the chain already, it is possible to send a request directly to that chain's validator +nodes. +This way, you don’t have to wait for the Tangle to process the message, significantly reducing the overall confirmation +time. +Due to the shorter delay, off-ledger requests are preferred over on-ledger requests unless you need to deposit assets to the chain. \ No newline at end of file diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_partials/how-tos/token/_check_storage_deposit.md b/docs/content/guides/developer/layer-2-smart-contracts/_partials/how-tos/token/_check_storage_deposit.md new file mode 100644 index 00000000000..f3b043b7ba5 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/_partials/how-tos/token/_check_storage_deposit.md @@ -0,0 +1,10 @@ +### 1. Check the Storage Deposit + +Check if the amount paid to the contract is the same as the required [storage deposit](/learn/protocols/stardust/core-concepts/storage-deposit) + and set the allowance. + +```solidity +require(msg.value == _storageDeposit*(10**12), "Please send exact funds to pay for storage deposit"); +ISCAssets memory allowance; +allowance.baseTokens = _storageDeposit; +``` \ No newline at end of file diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_partials/how-tos/token/_example_code_intro.mdx b/docs/content/guides/developer/layer-2-smart-contracts/_partials/how-tos/token/_example_code_intro.mdx new file mode 100644 index 00000000000..daf06c0839b --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/_partials/how-tos/token/_example_code_intro.mdx @@ -0,0 +1,9 @@ +import Ownership from '../../../_admonitions/_ownership.md'; +import Payable from '../../../_admonitions/_payable.md'; +import CheckStorageDeposit from './_check_storage_deposit.md' + + + + + + diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_partials/how-tos/token/_obsolete_token_creation.md b/docs/content/guides/developer/layer-2-smart-contracts/_partials/how-tos/token/_obsolete_token_creation.md new file mode 100644 index 00000000000..1a70e93ffaa --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/_partials/how-tos/token/_obsolete_token_creation.md @@ -0,0 +1,5 @@ +:::caution + +This method is now obsolete, use the new [`createNativeTokenFoundry`](../../../how-tos/core-contracts/token/create-native-token.md) method instead. + +::: \ No newline at end of file diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/consensus.md b/docs/content/guides/developer/layer-2-smart-contracts/explanations/consensus.md new file mode 100644 index 00000000000..539e7c15adb --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/explanations/consensus.md @@ -0,0 +1,53 @@ +--- +description: IOTA Smart Contracts consensus is how Layer 2 validators agree to change the chain state in the same way. +image: /img/logo/WASP_logo_dark.png +tags: + - smart contracts + - consensus + - validator committee + - validators + - validator nodes + - explanation +--- + +# Consensus + +To update the chain, its committee must reach a _consensus_, meaning that more than two thirds of its validators have to +agree to change the state in the exact same way. +This prevents a single malicious node from wreaking havoc over the chain, but there are also more mundane reasons for +individual nodes to act up. + +Smart contracts are deterministic. All honest nodes will produce the same output — but only if they have received the +same input. Each validator node has its point of access to the Tangle, so it may look different to different nodes, as +new transactions take time to propagate through the network. Validator nodes will receive smart contract requests with +random delays in a random order, and, finally, all computers run on their own always slightly skewed clocks. + +## Batch Proposals + +As the first step, each node provides its vision, a _batch proposal_. The proposal contains a local timestamp, a list of +unprocessed requests, and the node's partial signature of the commitment to the current state. + +Then the nodes must agree on which batch proposals they want to work on. In short, nodes A, B, and C have to confirm +that they plan to work on proposals from A, B, and C, and from no one else. As long as there are more than two thirds of +honest nodes, they will be able to find an _asynchronous common subset_ of the batch proposals. From that point, nodes +have the same input and will produce the same result independently. + +## The Batch + +The next step is to convert the raw list of batch proposals into an actual batch. All requests from all proposals are +counted and filtered to produce the same list of requests in the same order. +The partial signatures of all nodes are combined into a full signature that is then fed to a pseudo-random function that +sorts the smart contract requests. +Validator nodes can neither affect nor predict the final order of requests in the batch. (This protects ISC +from [MEV attacks](https://ethereum.org/en/developers/docs/mev/)). + +## State Anchor + +After agreeing on the input, each node executes every smart contract request in order, independently producing the same +new block. Each node then crafts a state anchor, a Layer 1 transaction that proves the commitment to this new chain +state. The timestamp for this transaction is derived from the timestamps of all batch proposals. + +All nodes then sign the state anchor with their partial keys and exchange these signatures. This way, every node obtains +the same valid combined signature and the same valid anchor transaction, which means that any node can publish this +transaction to Layer 1. In theory, nodes could publish these state anchors every time they update the state; in +practice, they do it only every approximately ten seconds to reduce the load on the Tangle. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/context.mdx b/docs/content/guides/developer/layer-2-smart-contracts/explanations/context.mdx new file mode 100644 index 00000000000..ac2507210f4 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/explanations/context.mdx @@ -0,0 +1,50 @@ +--- +description: The call context is a predefined parameter to each smart contract function, which allows you to access the functionality that the call environment provides. +tags: + - WasmLib + - smart contract setup + - Func and View functions + - ScFuncContext + - ScViewContext + - Schema Tool +image: /img/logo/WASP_logo_dark.png +--- + +# Call Context + +Understanding the call context is vital in leveraging the Wasm code within a sandboxed host environment effectively. The following section explains the distinction between different function calls and the role of WasmLib in setting up a smart contract. + +## Function Calls: Func and View + +Smart contract function calls come in two types, each having specific access levels to the smart contract state: + +### Funcs + +Func functions grants full mutable access, resulting in a state update. They accommodate both on-ledger and off-ledger requests, finalized once the state update is registered in the Tangle ledger. + +### Views + +View functions allow limited immutable access, **no state update occurs**. Views are ideal for quickly querying the contract's current state, they only facilitate off-ledger calls. + +## Using Func and View + +WasmLib offers distinct contexts for these function types, namely `ScFuncContext` for Func and `ScViewContext` for View, controlling the accessible functionality and enforcing usage constraints through compile-time type-checking. + +## Smart Contract Setup with WasmLib + +Setting up a smart contract requires the following: + +### Defining Funcs and Views + +Outline available Funcs and Views and communicate them to the host through WasmLib. +It ensures the correct dispatch of function calls and maintains necessary restrictions. + +### Parameter and Return Value Determination + +Establish the parameters and return values for each function. ISC uses simple dictionaries to store details, necessitating consistent (de)serialization handled adeptly by WasmLib. + +### Utilizing Schema Tool + +Although you can use the WasmLib directly, the Schema Tool is recommended for automatically generating and updating the smart contract framework in a type-safe manner, using the preferred language. + +Grasping these concepts will facilitate a secure and efficient smart contract setup, steering clear of potential pitfalls while making the most of what WasmLib offers. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/core-contracts.md b/docs/content/guides/developer/layer-2-smart-contracts/explanations/core-contracts.md new file mode 100644 index 00000000000..acfdbf5e22c --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/explanations/core-contracts.md @@ -0,0 +1,37 @@ +--- +description: There currently are 6 core smart contracts that are always deployed on each chain, root, _default, accounts, blob, blocklog, and governance. +image: /img/banner/banner_wasp_core_contracts_overview.png +tags: + - smart contracts + - core + - initialization + - request handling + - on-chain ledger + - accounts + - data + - receipts + - reference +--- + +# Core Contracts + +![Wasp Node Core Contracts Overview](/img/banner/banner_wasp_core_contracts_overview.png) + +There are currently 7 core smart contracts that are always deployed on each +chain. These are responsible for the vital functions of the chain and +provide infrastructure for all other smart contracts: + +- [`root`](../reference/core-contracts/root.md): Responsible for the initialization of the chain, maintains registry of deployed contracts. + +- [`accounts`](../reference/core-contracts/accounts.md): Manages the on-chain ledger of accounts. + +- [`blob`](../reference/core-contracts/blob.md): Responsible for the registry of binary objects of arbitrary size. + +- [`blocklog`](../reference/core-contracts/blocklog.md): Keeps track of the blocks and receipts of requests that were processed by the chain. + +- [`governance`](../reference/core-contracts/governance.md): Handles the administrative functions of the chain. For example: rotation of the committee of validators of the chain, fees and other chain-specific configurations. + +- [`errors`](../reference/core-contracts/errors.md): Keeps a map of error codes to error messages templates. These error codes are used in request receipts. + +- [`evm`](../reference/core-contracts/evm.md): Provides the necessary infrastructure to accept Ethereum + transactions and execute EVM code. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/how-accounts-work.md b/docs/content/guides/developer/layer-2-smart-contracts/explanations/how-accounts-work.md new file mode 100644 index 00000000000..8847cb2c883 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/explanations/how-accounts-work.md @@ -0,0 +1,102 @@ +--- +description: 'IOTA Smart Contracts chains keep a ledger of on-chain account balances. On-chain accounts are identified +by an AgentID.' +image: /img/tutorial/accounts.png +tags: + +- smart contracts +- on-chain account +- ownership +- accounts Contract +- explanation + +--- +# How Accounts Work + +On the L1 Ledger, like with any _DLT_, we have **trustless** and **atomic** transfers of assets between addresses on the +ledger. + +Tokens controlled by an address can be moved to another address by providing a valid signature using the private key +that controls the source address. + +## L1 Addresses + +In IOTA Smart Contracts, [each chain has a L1 address](../explanations/states.md#digital-assets-on-the-chain) (also known as the _Chain +ID_) which enables it to control L1 assets (base tokens, native tokens and NFTs). +The chain acts as a custodian of the L1 assets on behalf of different entities, thus providing a _L2 Ledger_. + +## L2 Accounts + +The L2 ledger is a collection of _on-chain accounts_ (sometimes called just _accounts_). +L2 accounts can be owned by different entities, identified by a unique _Agent ID_. +The L2 ledger is a mapping of Agent ID => balances of L2 assets. + +## Types of Accounts + +### L1 Address + +Any L1 address can be the owner of a L2 account. +The Agent ID of an L1 address is just the address, + +e.g. `iota1pr7vescn4nqc9lpvv37unzryqc43vw5wuf2zx8tlq2wud0369hjjugg54mf`. + +Tokens in an address account can only be moved through a request signed by the private key of the L1 address. + +### Smart Contract + +Any _smart contract_ can be the owner of a L2 account. Recall that a smart +contract is uniquely identified in a chain by a [_hname_](smart-contract-anatomy.md#identifying-a-smart-contract). +However, the hname is not enough to identify the account since a smart contract on another chain could own it. + +Thus, the Agent ID of a smart contract is composed as the contract hname plus the [_chain +ID_](states.md#digital-assets-on-the-chain), with syntax `@`. For +example: `cebf5908@tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd`. + +Note that this allows trustless transfers of assets between smart contracts on the same or different chains. + +Tokens in a smart contract account can only be moved by that smart contract. + +### The Common Account + +The chain owns a unique L2 account, called the _common account_. +The common account is controlled by the chain owner (defined in the chain root contract) and is used to store funds +collected by fees or sent to the chain L1 address. + +The Agent ID of the common account is `@
`. + +### Ethereum Address + +An L2 account can also be owned by an Ethereum address. See [EVM](../introduction.md) for more information. +The Agent ID of an Ethereum address is just the address prefixed with `0x`, +e.g. `0xd36722adec3edcb29c8e7b5a47f352d701393462`. + +Tokens in an Ethereum account can only be moved by sending an Ethereum transaction signed by the same address. + +## The Accounts Contract + +The [`accounts` core contract](../reference/core-contracts/accounts.md) is responsible for managing the L2 ledger. +By calling this contract, it is possible to: + +- [View current account balances](../how-tos/core-contracts/basics/get-balance.md) +- [Deposit funds to the chain](../how-tos/send-funds-from-L1-to-L2.mdx) +- [Withdraw funds from the chain](../how-tos/core-contracts/basics/send-assets-to-l1.mdx) + +## Example + +The following diagram illustrates an example situation. +The IDs and hnames are shortened for simplicity. + +[![Example situation. Two chains are deployed, with three smart contracts and one address.](/img/tutorial/accounts.png)](/img/tutorial/accounts.png) + +Two chains are deployed, with IDs `chainA` and `chainB`. +`chainA` has two smart contracts on it (with hnames `3037` and `2225`), and `chainB` has one smart contract (`7003`). + +There is also an address on the L1 Ledger: `iota1a2b3c4d`. +This address controls 1337 base tokens and 42 `Red` native tokens on the L1 Ledger. + +The same address also controls 42 base tokens on `chainA` and 8 `Green` native tokens on `chainB`. + +So, the owner of the private key behind the address controls three different accounts: the L1 account and one L2 account +on each chain. + +Smart contract `7003@chainB` has five base tokens on its native chain and controls eleven base tokens on chain A. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/invocation.md b/docs/content/guides/developer/layer-2-smart-contracts/explanations/invocation.md new file mode 100644 index 00000000000..28756fd0713 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/explanations/invocation.md @@ -0,0 +1,108 @@ +--- +description: 'Smart contracts can be invoked through their entry points, from outside via a request, or from inside via a +call.' +image: /img/logo/WASP_logo_dark.png +tags: + +- smart contracts +- requests +- on-ledger +- off-ledger +- calls +- invocation +- explanation + +--- + +import OnOffLedgerRequest from '../_partials/_on_off_ledger_request.md'; + +# Calling a Smart Contract + +## Entry Points + +Like any other computer program, a smart contract will lie dormant until someone or something instructs it to activate. +In the case of smart contracts, the most common way to activate them is to call one of +their [entry points](./smart-contract-anatomy.md#entry-points). It is the same as calling a program's function. It will +take a set of instructions of the smart contract and execute it over the current chain's state. _View entry points_ can +only read the state, while _full entry points_ can read and write to it. + +To invoke a smart contract from outside the chain, the _sender_ (some entity that needs to be identified by a +private/public key pair) has to wrap the call to the entry point into a _request_. +The request has to be cryptographically signed and submitted to the [consensus](./consensus.md) procedure to let the +chain's committee evaluate it and engrave the outcome of its execution into a new state update. + +Upon receiving a request, the committee will execute the wrapped call fully or reject the request with all its potential +changes, never modifying the state halfway. This means that every single request is an atomic operation. + +### Synchronous Composability + +After being invoked by a request, the smart contract code is allowed to invoke entry points of other smart contracts on +the same chain. This means it can _call_ other smart contracts. + +Smart contract calls are deterministic and synchronous, meaning they always produce the same result and execute all +instructions immediately after another. +If a smart contract calls another smart contract, the resulting set of instructions is also deterministic and +synchronous. This means that for a request, it makes no difference if a smart contract's entry point contains the whole +set of instructions or if it is composed by multiple calls to different smart contracts of the chain. + +Being able to combine smart contracts in this way is called _synchronous composability_. + +--- + +## Requests + +A request contains a call to a smart contract and a signature of the sender. The sender also owns the assets and funds +processed within the request. +Unlike calls between smart contracts, requests are not executed immediately. +Instead, they must wait until the chain's _validator_ nodes include them in a request batch. +This means that requests have a delay and are executed in an unpredictable order. + +### Asynchronous Composability + +Requests are not sent by humans exclusively. Smart contracts can also create requests. +For example, a user can send a request to a smart contract that, in turn, sends a request to a decentralized third-party +exchange which would will the user's funds from one currency to another and send them back through another request. + +This is called _asynchronous composability_. + + + +--- + +## Gas + +Gas expresses the "cost" of running a request in a chain. Each operation (arithmetics, write to disk, dispatch events, +etc.) has an associated gas cost. The amount of gas required for a transaction depends on the complexity of the +operation. For example, simple transfers may require less gas, while interacting with smart contracts for actions such +as token swaps can require more due to the higher computational work involved. + +For users to specify how much they're willing to pay for a request, they need to specify a `GasBudget` in the request. +This gas budget is the "maximum operations that this request can execute" and will be charged as a fee based on the +chain's current [fee policy](../reference/core-contracts/governance.md#fee-policy). + +The funds to cover the gas used will be charged directly from the user's on-chain account. + +--- + +## Allowance + +An allowance is a feature within smart contracts that controls how much one address can spend on behalf +of another address. Before a third party can withdraw tokens from your account, you must explicitly set an allowance for +that third party's address, specifying the maximum amount of tokens they are allowed to transfer. This mechanism is used +in various decentralized finance (DeFi) applications, where you might allow a smart contract to interact with your +tokens to participate in staking, lending, or trading activities. The original token owner can adjust or revoke the +allowance at any time, providing control over how your tokens are used by others. + +Any funds sent to the chain are credited to the sender's account. If you want a contract to use +those funds, you must specify an `Allowance` in the request. Contracts can then claim any of the allowed funds using +the sandbox `TransferAllowedFunds` function. + +The Allowance property looks like the following: + +```go +{ + BaseTokens: uint64 + NativeTokens: [{TokenID, uint256}, ...] + NFTs: [NFTID, ...] +} +``` diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/sandbox.md b/docs/content/guides/developer/layer-2-smart-contracts/explanations/sandbox.md new file mode 100644 index 00000000000..d5ff9a7add4 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/explanations/sandbox.md @@ -0,0 +1,45 @@ +--- +description: 'Smart Contracts can only interact with the world by using the Sandbox interface which provides limited and +deterministic access to the state through a key/value storage abstraction.' +image: /img/sandbox.png +tags: + +- smart contracts +- sandbox +- interface +- storage abstraction +- explanation + +--- + +# Sandbox Interface + +A smart contract's access to the world has to be restricted. Imagine a smart contract that would directly tap into a +weather forecast website: as the weather changes, the result of the contract's execution will also change. This smart +contract is not deterministic, meaning that you cannot reproduce the result yourself to verify it because the result for +each execution could be different. + +The access to the chain's state has to be curated, too. The chain owner and developers of individual smart contracts are +not necessarily the same entity. A single malicious contract could ruin the whole chain if not limited to its own space. +Instead of working on the state as a whole, each smart contract can only modify a part of it. + +The only way for smart contracts to access data is to use the sandbox interface, which is deterministic. It provides +their internal state as a list of key/value pairs. + +![Sandbox](/img/sandbox.png) + +Besides reading and writing to the contract state, the Sandbox interface allows smart contracts to access: + +- The [ID](how-accounts-work.md) of the contract. +- The details of the current request or view call. +- The current request allowance and a way to claim the allowance. +- The balances owned by the contract. +- The ID of whoever had deployed the contract. +- The timestamp of the current block. +- Cryptographic utilities like hashing, signature verification, and so on. +- The [events](../schema/how-tos/events.mdx) dispatch. +- Entropy that emulates randomness in an unpredictable yet deterministic way. +- Logging. Used for debugging in a test environment. + +The Sandbox API available in "view calls" is slightly more limited than the one available in normal "execution calls". +For example, besides the state access being read-only for a view, they cannot issue requests, emit events, etc. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/smart-contract-anatomy.md b/docs/content/guides/developer/layer-2-smart-contracts/explanations/smart-contract-anatomy.md new file mode 100644 index 00000000000..aa5539626a9 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/explanations/smart-contract-anatomy.md @@ -0,0 +1,77 @@ +--- +description: Each smart contract instance has a program with a collection of entry points and a state. +image: /img/tutorial/SC-structure.png +tags: + - smart contracts + - structure + - state + - entry points + - Wasm + - explanation +--- + +# Anatomy of a Smart Contract + +Smart contracts are programs that are immutably stored in the chain. + +Through _VM abstraction_, the ISC virtual machine is agnostic about the interpreter used to execute each smart contract. +It can support different _VM types_ (i.e., interpreters) simultaneously on the same chain. +For example, it is possible to have [Wasm](../getting-started/languages-and-vms.md#wasm-vm-for-isc) and [EVM/Solidity](../getting-started/languages-and-vms.md#evmsolidity-based-smart-contracts) smart +contracts coexisting on the same chain. + +![Smart Contract Structure](/img/tutorial/SC-structure.png) + +## Identifying a Smart Contract + +The ISC [core contracts](core-contracts.md) and WASM contracts on the chain are identified by a _hname_ (pronounced +"aitch-name"), which is a `uint32` value calculated as a hash of the smart contract's instance name (a string). +For example, the hname of the [`root`](../reference/core-contracts/root.md) core contract +is `0xcebf5908`. This value uniquely identifies this contract in every chain. This does not apply to EVM contracts. + +## State + +The smart contract state is the data owned by the smart contract and stored on the chain. +The state is a collection of key/value pairs. +Each key and value are byte arrays of arbitrary size (there are practical limits set by the underlying database, of +course). +You can think of the smart contract state as a partition of the chain's data state, which can only be written by the +smart contract program itself. + +The smart contract also owns an account on the chain, stored as part of the chain state. +The smart contract account represents the balances of base tokens, native tokens, and NFTs controlled by the smart +contract. + +The smart contract program can access its state and account through an interface layer called the _Sandbox_. +Only the smart contract program can change its data state and spend from its +account. Tokens can be sent to the smart contract account by any other agent on +the ledger, be it a wallet with an address or another smart contract. + +See [Accounts](./how-accounts-work.md) for more information on sending and receiving +tokens. + +## Entry Points + +Each smart contract has a program with a collection of _entry points_. +An entry point is a function through which you can invoke the program. + +There are two types of entry points: + +- _Full entry points_ (or simply _entry points_): These functions can modify + (mutate) the smart contract's state. +- _View entry points_ (or _views_): These are read-only functions. They are only used + to retrieve the information from the smart contract state. They cannot + modify the state, i.e., they are read-only calls. + +## Execution Results + +After a request to a Smart Contract is executed (a call to a full entry point), a _receipt_ will be added to +the [`blocklog`](../reference/core-contracts/blocklog.md) core contract. The receipt details the +execution results +of said request: whether it was successful, the block it was included in, and other information. +Any events dispatched by the smart contract in context of this execution will also be added to the receipt. + +## Error Handling + +Smart contract calls can fail: for example, if they are interrupted for any reason (e.g., an exception) or if it +produces an error (missing parameter or other inconsistency). +Any gas spent will be charged to the sender, and the error message or value is stored in the receipt. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/smart-contracts.md b/docs/content/guides/developer/layer-2-smart-contracts/explanations/smart-contracts.md new file mode 100644 index 00000000000..b7b194d8749 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/explanations/smart-contracts.md @@ -0,0 +1,54 @@ +--- +description: 'Smart contracts are applications you can trust that run on a distributed network with multiple validators +all executing and validating the same code.' +image: /img/banner/banner_wasp_core_concepts_smart_contracts.png +tags: + +- smart contracts +- blockchain +- parallel +- scaling +- explanation + +--- + +# Smart Contracts + +![Wasp Node Smart Contracts](/img/banner/banner_wasp_core_concepts_smart_contracts.png) + +## What Are Smart Contracts? + +Smart contracts are software applications that run on a distributed network with multiple validators executing and +validating the same code. This ensures the application behaves as expected and that there is no tampering in the +program's execution. + +### Applications You Can Trust + +As you can be certain that the executed code is always the same (and will not change), this results in +applications you can trust. This allows you to use smart contracts for applications with a trust issue. The +smart contract rules define what the contract can and can not do, making it a decentralized and predictable +decision-maker. + +You can use smart contracts for all kinds of purposes. A recurring reason to use a smart contract is to automate +specific +actions without needing a centralized entity to enforce this specific action. A good example is a smart contract +that can exchange a certain amount of IOTA tokens for land ownership. The smart contract will accept +both the IOTA tokens and the land ownership, and will predictably exchange them between both parties without the risk of +one of the parties not delivering on their promise. **With a smart contract, code is law**. + +### Scalable Smart Contracts + +Anyone willing to pay the fees for deploying a smart contract on a public blockchain can deploy one. Once your smart +contract has been deployed to the chain, you no longer have the option to change it, and you can be sure that your +smart contract application will be there as long as that blockchain exists. Smart contracts can communicate with one +another, and you can invoke programmed public functions on a smart contract to trigger actions on a smart contract, or +address the state of a smart contract. + +Because smart contracts do not run on a single computer but on many validators, a network of validators can only +process so many smart contracts at once, even if the software has been written optimally. This means smart contracts are +expensive to execute, and do not scale well on a single blockchain, often resulting in congested networks and costly +fees for executing functions on smart contracts. **By allowing many blockchains executing smart contracts to run in +parallel** and communicate with one another, **IOTA Smart Contracts solves this scalability problem.** + +At the same time, ISC provides advanced means of communication between its chains and preserves the ability to create +complex, composed smart contracts. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/state_manager.md b/docs/content/guides/developer/layer-2-smart-contracts/explanations/state_manager.md new file mode 100644 index 00000000000..dcbbf0c9e06 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/explanations/state_manager.md @@ -0,0 +1,209 @@ +--- +description: State manager is Wasp component, which is responsible for keeping the store up to date. +image: /img/logo/WASP_logo_dark.png +tags: + - state manager + - pruning + - snapshot + - write ahead log + - WAL +--- + +# State Manager + +State manager aims at keeping the state of the node up to date by retrieving missing data and ensuring that it is +consistently stored in the DB. It services requests by other Wasp components (consensus, _mempool_), which mainly +consist of ensuring that the required state is available in the node: that it may be retrieved from the permanent +store of the node (the database; DB). An obvious way to obtain the latest state is to obtain all of the blocks, +that resulted in making that state. So to obtain state index `n`, state manager first must commit block index `0` +(origin block), then block index `1`, then block index `2` etc. up to block index `n` precisely in that order. +There are two ways for state manager to obtain blocks (other than origin block): + +1. Receive them directly from this node's consensus when the new state[^1] is decided. State manager has no influence + to this process. +2. Receive them from neighbouring nodes upon request, provided the block is available there. + +Independently of the way the block is received, it is stored in state manager's cache (for quicker access) and WAL +(to ensure availability). Therefore it may happen that the block can be retrieved from there. + +[^1] A block is a difference between two consecutive states. To make state index `n`, block index `n` must be obtained +and committed on top of state index `n-1`. Although state manager manipulates blocks, in this description sometimes +"state" and "block" will be used interchangeably as "obtaining block" or "committing block" is essentially the same as +"obtaining state" or "committing state" respectively, having in mind that previous state is already obtained or committed. Block +and state has some other common properties, e.g. block index `n`, which applied to state index `n-1` produces state index `n`, +contains the same commitment as state index `n`. + +## Snapshot + +Once in a while there might be a need to add a new node to the network. This node has no knowledge of chain's history +and it still needs to have the newest state of the chain (to catch up the chain). If the chain has been running for a while, +it might have gone through many sate transitions and downloading that many blocks may take a long period of time. To avoid that, +some nodes in the network can be configured to dump a complete state of the chain at some time into a file periodically +(see `snapshots.period` parameter). This file is called a snapshot. Loading a snapshot to DB produces the same state as downloading +and committing all the blocks that produced that state. However as those blocks aren't downloaded, they are not available in the DB, +except a block with the same state index as snapshot. + +The snapshot format is as follows: + +1. number `4` in 4 byte unsigned integer little endian format representing the length of state index, +2. state index in 4 byte unsigned integer little endian format, +3. number `40` in 4 byte unsigned integer little endian format representing the length of state commitment: `20` bytes for trie root and + `20` bytes for hash of a block, which was last committed to make this state (block with the same index as state), +4. trie root in `20` bytes, +5. the mentioned block's hash in `20` bytes, +6. number `0` in 1 byte unsigned integer format representing snapshot version, +7. bytes representing mentioned block, +8. bytes representing trie of the state. + +The node that makes a snapshot can serve it over http and new nodes can use this to speed up the catch up. Serving the snapshots +over http is beyond the scope of Wasp and should be done in addition. Wasp is only responsible for making snapshots in local +(configurable by `snapshots.localPath` parameter) folder and obtaining them on start when needed from the same local folder or from +configured (by `snapshots.networkPaths` parameter) URLs. A folder, referenced in the `snapshots.networkPaths` parameter must contain +`INDEX` file with new line separated list of snapshot file names. + +If a chain starts with an empty database (usually if the database hasn't been created yet or was deleted), the node checks if +it can load a snapshot: it scans the local folder and all the network addresses for available snapshot files. In the local folder, it reads +all the files with names that satisfy the search pattern `*-*.snap`. In each network location, Wasp reads all the files listed in `INDEX` +file of that location. Wasp reads a state index and a commitment from the contents of these files. File names are not used to obtain +this information, and full snapshot files are not (down)loaded yet. The node chooses +the one with the largest state index and loads it to the store among all available snapshot files. If several files have the same largest state index, +the node loads them one by one, starting from the local ones until one snapshot is loaded correctly. If loading fails for all candidates, +the node will start with an empty database. + +You can use the `snapshots.snapshotsToLoad` parameter to load a specific snapshot. In that case, the node searches for snapshots with +the block hash provided in the parameter. Once again, if loading all found files fails, the node starts with an empty database. + +After a snapshot is loaded, earlier blocks (ones with a smaller state index than the snapshot) cannot be retrieved and committed to the DB +(this is discussed in [Obtaining blocks section](#obtaining-blocks)). This constraint can cause problems (especially in reorg) +if the loaded snapshot is too recent. To avoid that, making snapshots is delayed by `snapshots.delay` states. E.g., if `snapshots.period` +is `100` and `snapshots.delay` is `20`, then snapshot index `100` will be produced. When block index `120` is committed, snapshot index +`200` will be produced, when snapshot index `220` is committed, etc... For the data to be available after this delay, `snapshot.delay` +value must be considerably smaller than `stateManager.pruningMinStatesToKeep`. + +## Obtaining blocks + +Requests to the state manager contain the state commitment and the state manager must ensure, that block (state) with this +commitment is present in the DB. It is possible that to satisfy the request state manager needs to retrieve +several blocks. However this cannot be done in one step as only the commitment of the requested block is known. For this +reason state (block) contains a commitment of the previous block. Previous block must be committed prior to committing the +requested block. And this logic can be extended up to the block, which is already present in the DB, or until the origin +state is reached. + +E.g., let's say, that the last state in the DB is state index `10` and request to have state index `12` is received. +State manager does this in following steps: + +1. Block index `12` is obtained, and commitment of block index `11` is known. +2. As the commitment of block (state) index `11` is known, the block may be requested and obtained. After obtaining block + index `11` commitment of block index `10` is known. +3. Using block index `10` commitment the DB is checked to make sure that it is already present. +4. As block index `10` is already committed, block index `11` is committed. This makes state `11` present in the DB. +5. As state `11` is already committed, block index `12` is committed. This makes state `12` present in the DB and completes + the request. + +To obtain blocks, state manager sends requests to 5 other randomly chosen nodes. If the block is not received (either messages +got lost or these nodes do not have the requested block), 5 other randomly chosen nodes are queried. This process is repeated +until the block is received (usually from other node but may also be from this node's consensus) or the request is no longer +valid. + +If difference between state indexes of requested state and available in the DB state is large, this chain can get very long. +In order to limit its length, if requested block index is a) smaller than state index of snapshot, which was loaded on node +start, or b) smaller than largest state index among the pruned blocks (see [Pruning](#pruning)), the node panics. If this panicking +continues, the administrator may decide to delete the DB and start the node from (possibly configured) snapshot. + +## Block cache + +Block cache is in memory block storage. It keeps a limited amount (configured by `stateManager.blockCacheMaxSize`) of blocks +for limited amount of time (configured by `stateManager.blockCacheBlocksInCacheDuration`) to make the retrieval +quicker. E.g., in the last step of example of the previous section block index `12` must be committed. It is obtained in +the step 1, but as several steps of the algorithm are spread over time with requests to other nodes in between, and +several requests to obtain the same block may be present, it is not feasible to store it in request. However it would +be wasteful to fetch it twice on the same request. So the block is stored in cache in step 1 of the algorithm and +retrieved from cache later in the last step. + +The block is kept in the cache no longer that predetermined amount of time (configured by `stateManager.blockCacheBlocksInCacheDuration`). +If upon writing to cache blocks in cache limit is exceeded, block, which is in cache the longest, is removed from cache. + +## Block write ahead log (WAL) + +Upon receiving a block, its contents is dumped into a file and stored in a file system. The set of such files is WAL. + +The primary motivation behind creating it was in order not to deadlock the chain. Upon deciding on next state committee +nodes send the newest block to state manager and at the same time one of the nodes send the newest transaction to L1. +In an unfavourable chain of events it might happen that state managers of the committee nodes are not fast enough to commit +the block to the DB (see algorithm in [Obtaining blocks section](#obtaining-blocks)), before the node crashes. This leaves +the nodes in the old state as none of the nodes had time to commit the block. However the L1 reports the new state as +the latest although none of the nodes can be transferred to it. The solution is to put the block into WAL as soon as +possible so it won't be lost. + +Currently upon receiving the new confirmed block from node's consensus, state manager is sure that its predecessor is in the DB, +because consensus sends other requests before sending the new block, so WAL isn't that crucial any more. However, it is useful +in several occasions: + +1. Storing preliminary block, which is sent by consensus of other nodes. +2. When the node is catching up many states and block cache limit is too small to store all the blocks, WAL is used to avoid + fetching the same block twice. +3. In case of adding new node to the network to avoid catch up taking a lot of time when snapshots are not available, + the new node can be configured (`wal.loadToStore=true`) to load the DB with blocks from WAL on startup. WAL can be copied + from some other node. This is also true for any catch up over many states. + +## Pruning + +In order to limit the DB size, old states are deleted (pruned) from it on a regular basis. The amount of states to keep is +configured by two parameters: one in the configuration of the node (`stateManager.pruningMinStatesToKeep`) and one in the governance contract +(`BlockKeepAmount`). The resulting limit of previous states to keep is the larger of the two. Every time a block is committed +to the DB, states which are over the limit are pruned. However, to avoid freezing State manager for too long, no more than +`stateManager.pruningMaxStatesToDelete` blocks are pruned in a single run. The algorithm ensures that oldest states are pruned +first to avoid gaps between available states on the event of some failure. + +Pruning may be disabled completely via node configuration to make an archive node: node that contains all the state ever +obtained by the chain. Note, that such node will require a lot of resources to maintain: mainly disk storage. + +## Parameters + +### State manager + +The following parameters may be provided in section `stateManager`: + +- `blockCacheMaxSize`: the limit of the blocks in block cache. Default is 1k. +- `blockCacheBlocksInCacheDuration`: the limit of the time block stays in block cache. Default is 1 hour. +- `blockCacheBlockCleaningPeriod`: how often state manager should find and delete blocks, that stayed in block cache + for too long. Default is every minute. +- `stateManagerGetBlockRetry`: how often requests to retrieve the needed blocks from other nodes should be repeated. + Default is every 3 seconds. +- `stateManagerRequestCleaningPeriod`: how often state manager should find and delete requests, that are no longer valid. + Default is every second. +- `stateManagerTimerTickPeriod`: how often state manager should check if some maintenance (cleaning requests or block cache, + resending requests for blocks) is needed. Default is every second. There is no point in making this value larger than + any of `blockCacheBlockCleaningPeriod`, `stateManagerGetBlockRetry` or `stateManagerRequestCleaningPeriod`. +- `pruningMinStatesToKeep` : minimum number of old states to keep in the DB. Note that if `BlockKeepAmount` in + governance contract is larger than this value, then more old states will be kept. + Default is 10k. 0 (and below) disables pruning. +- `pruningMaxStatesToDelete`: maximum number of states to prune in one run. This is needed in order not to grab + state manager's time for pruning for too long. Default is 1k. + +### Snapshots + +The following parameters may be provided in section `snapshots`: + +- `snapshotsToLoad`: the comma sepparated list of `:` pairs, where chain `` must be started using snapshot with block hash ``. + The list can also contain `` entry. This hash will be used for other chains, which are not configured separately. There is + no point in having several `` or `:` entries with the same `` as only the last such entry is taken into + account. Note that if the chain is configured to start from some snapshot and the snapshot is not available (or another error occurs + during snapshot loading), the chain will start with an empty DB. The default is an empty list, which means that the newest available snapshot + will be loaded for every chain. +- `period`: how often state snapshots should be made: 1000 meaning "every 1000th state", 0 meaning "making snapshots is disabled". + Snapshots are disabled by default. +- `delay`: how many states to delay making the snapshot; it must be considerably smaller than `stateManager.pruningMinStatesToKeep`. + The default is 20. +- `localPath`: the path to the snapshots folder in this node's disk. Default is `waspdb/snap`. +- `networkPaths`: the comma-separated list of URLs that serve snapshots. The URLs may have the HTTP (e.g., `http://server.org/path/`) or the HTTPS + (e.g., `https://server.org/path/`) scheme for remote locations or a file path (e.g., `file://path/to/folder`) scheme for local snapshot locations. + The scheme is compulsory in the URL. The list is empty by default. + +### WAL + +The following parameters may be provided in section `wal`: + +- `loadToStore`: load blocks from WAL to the store on node start-up. This function is off (`false`) by default. +- `enabled`: whether the WAL is enabled. It is enabled by default. +- `path`: the path to the WAL folder. Default is `waspdb/wal`. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/states.md b/docs/content/guides/developer/layer-2-smart-contracts/explanations/states.md new file mode 100644 index 00000000000..819068b9aaf --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/explanations/states.md @@ -0,0 +1,122 @@ +--- +description: 'The state of the chain consists of balances of native IOTA digital assets and a collection of key/value +pairs which represents use case-specific data stored in the chain by its smart contracts outside the UTXO ledger.' +image: /img/chain0.png +tags: + +- state +- transitions +- balances +- digital assets +- UTXO +- transitions +- explanation +--- + +# State, Transitions, and State Anchoring + +## State of the Chain + +The state of the chain consists of: + +- A ledger of accounts owning IOTA _digital assets_ (base tokens, native tokens, and NFTs). The chain acts as a custodian + for those funds on behalf of each account's owner. +- A collection of arbitrary key/value pairs (the _data state_) that contains use case-specific data stored by the smart + contracts in the chain. + +The chain's state is an append-only (immutable) _data structure_ maintained by the distributed consensus of its +validators. + +## Digital Assets on the Chain + +Each native L1 account in the IOTA UTXO ledger is represented by an address and controlled by an entity holding the +corresponding private/public key pair. +In the UTXO ledger, an account is a collection of UTXOs belonging to the address. + +Each ISC L2 chain has a L1 account, called the _chain account_, holding all tokens entrusted to the chain in a single +UTXO, the _state output_. +It is similar to how a bank holds all deposits in its vault. This way, the chain (the entity controlling the state +output) becomes a custodian for the assets owned by its clients, similar to how the bank’s client owns the money +deposited in the bank. + +The consolidated assets held in the chain are the _total assets on-chain_, which are contained in the state output of +the chain. + +The chain account is controlled by a _chain address_, also known as _chain ID_. +It is a special kind of L1 address, an _alias address_, which abstracts the controlling entity (the state controller +address) from the identity of the chain: the controlling entity of the chain may change, while the chain ID stays the +same. + +## The Data State + +The data state of the chain consists of a collection of key/value pairs. +Each key and each value are arbitrary byte arrays. + +In its persistent form, the data state is stored in a key/value database outside the UTXO ledger and maintained by the +validator nodes of the chain. +The state stored in the database is called the _solid state_. + +While a smart contract request is being executed, the _virtual state_ is an in-memory collection of key/value pairs that +can become solid upon being committed to the database. +An essential property of the virtual state is the possibility of having several virtual states in parallel as +candidates, with a possibility for one of them to be solidified. + +The data state has a state hash, a timestamp, and a state index. +The state hash is usually a Merkle root, but it can be any hashing function of all data in the data state. + +The data state hash and on-chain assets are contained in a single atomic unit on the L1 ledger: the state UTXO. +Each state mutation (state transition) of the chain is an atomic event that changes the on-chain assets and the data +state, consuming the previous state UTXO and producing a new one. + +## Anchoring the State + +The data state is stored outside the ledger, on the distributed database maintained by _validator_ nodes. +_Anchoring the state_ means placing the hash of the data state into the state UTXO and adding it to the L1 UTXO ledger. +The UTXO ledger guarantees that there is _exactly one_ such output for each chain on the ledger at every moment. +We call this output the _state output_ (or state anchor) and the containing transaction the _state transaction_ (or +anchor transaction) of the chain. +The state output is controlled (i.e., can be unlocked/consumed) by the entity running the chain. + +With the anchoring mechanism, the UTXO ledger provides the following guarantees to the IOTA Smart Contracts chain: + +- There is a global consensus on the state of the chain +- The state is immutable and tamper-proof +- The state is consistent (see below) + +The state output contains: + +- The identity of the chain (its L1 alias address) +- The hash of the data state +- The state index, which is incremented with each new state output + +## State Transitions + +The data state is updated by mutations of its key/value pairs. +Each mutation either sets a value for a key or deletes a key (and the associated value). +Any update to the data state can be reduced to a partially ordered sequence of mutations. + +A _block_ is a collection of mutations to the data state that is applied in a state transition: + +```go +next data state = apply(current data state, block) +``` + +The state transition in the chain occurs atomically in a L1 transaction that consumes the previous state UTXO and +produces the next one. The transaction includes the movement of the chain's assets and the update of the state hash, + +At any moment in time, the data state of the chain is a result of applying the historical sequence of blocks, starting +from the empty data state. + +![State transitions](/img/chain0.png) + +On the L1 UTXO ledger, the state's history is represented as a sequence (chain) of UTXOs, each holding the chain’s +assets in a particular state and the anchoring hash of the data state. +Note that not all the state's transition history may be available: due to practical reasons, older transactions may be +pruned in a snapshot process. +The only thing guaranteed is that the tip of the chain of UTXOs is always available (which includes the latest data +state hash). + +The ISC virtual machine (VM) computes the blocks and state outputs that anchor the state, which ensures that the state +transitions are calculated deterministically and consistently. + +![Chain](/img/chain1.png) diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/validators.md b/docs/content/guides/developer/layer-2-smart-contracts/explanations/validators.md new file mode 100644 index 00000000000..97ed59a19c0 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/explanations/validators.md @@ -0,0 +1,49 @@ +--- +description: Each chain is run by a network of validator nodes which run a consensus on the chain state update. +image: /img/logo/WASP_logo_dark.png +tags: + - validators + - validator nodes + - access nodes + - consensus + - state update + - explanation +--- + +# Validators + +Each chain is run by that chain's _committee of validators_. This committee owns a key that is split between all of its +validators. Each key share is useless on its own, but a collective signature gives validators complete control over the +chain. + +The committee of validators is responsible for executing the smart contracts in the chain and thus calculating a _state +update_. +All validators execute exactly the same code and reach a consensus on the state update. +Once the next state is computed and validated, it is committed to each validator's database, a new _block_ is added to +the chain (containing the state mutations), and the _state hash_ is saved in the L1 ledger. + +Depending on the governance model, chain owners can rotate the committee of validators. +By rotating the committee of validators, validators can be deleted, added, or replaced. + +ISC does not define how to select validators to form a committee: it could be a solitary choice of the chain's owner, or +it could be a public competition between candidates. +ISC does not define how validators are rewarded either. + +## Access Nodes + +It is possible to have some nodes act as _access nodes_ to the chain without being part of the committee of +validators. +All nodes in the subnet (validators and non-validators) are connected through statically assigned trust +relationships and each node is also connected to the IOTA L1 node to receive updates on the chain’s L1 +account. + +Any node can optionally provide access to smart contracts for external callers, allowing them to: + +- Query the state of the chain (i.e., _view calls_) +- Send off-ledger requests directly to the node (instead of sending an on-ledger request as a L1 transaction) + +It is common for validator nodes to be part of a private subnet and have only a group of access nodes exposed to the +outside world, protecting the committee from external attacks. + +The management of validator and access nodes is done through +the [`governance` core contract](../reference/core-contracts/governance.md). diff --git a/docs/content/guides/developer/layer-2-smart-contracts/getting-started/compatibility.md b/docs/content/guides/developer/layer-2-smart-contracts/getting-started/compatibility.md new file mode 100644 index 00000000000..94cd946d381 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/getting-started/compatibility.md @@ -0,0 +1,46 @@ +--- +description: Compatibility between the ISC EVM layer and existing Ethereum smart contracts and tooling. +image: /img/logo/WASP_logo_dark.png +tags: + - smart contracts + - EVM + - Ethereum + - Solidity + - limitations + - compatibility + - fees + - reference +--- + +# EVM Compatibility in IOTA Smart Contracts + +The [`evm`](../reference/core-contracts/evm.md) [core contract](../reference/core-contracts/overview.md) +provides EVM support in IOTA Smart Contracts. It stores the EVM state (account balances, state, code, +etc.) and provides a way to execute EVM code to manipulate the state. + +The EVM core contract runs on top of the ISC layer, which provides the rest of the machinery needed to run smart +contracts, such as signed requests, blocks, state, proofs, etc. + +However, the ISC EVM layer is also designed to be as compatible as possible with existing Ethereum tools +like [MetaMask](https://metamask.io/), which assume that the EVM code runs on an Ethereum blockchain composed of +Ethereum blocks containing Ethereum transactions. Since ISC works in a fundamentally different way, +providing 100% compatibility is not possible. We do our best to emulate the behavior of an Ethereum node, so the +Ethereum tools think they are interfacing with an actual Ethereum node, but some differences in behavior are inevitable. + +## Properties and Limitations + +Here are some of the most important properties and limitations of EVM support in IOTA Smart Contracts: + +### No Enforced Block Time + +There is no guaranteed _block time_. A new EVM "block" will be created only when an ISC block is created, and ISC does +not enforce an average block time. This means that block times are variable; a new block will be created as soon as needed. + +### The Magic Contract + +A [dedicated Ethereum contract](../how-tos/core-contracts/introduction.md) exists to manage Layer 1 tokens and ISC +functionalities, introducing commands like `isc.send(...)` for token transfers. + +### Gas Fees + +Gas fees are set by the chain. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/getting-started/languages-and-vms.md b/docs/content/guides/developer/layer-2-smart-contracts/getting-started/languages-and-vms.md new file mode 100644 index 00000000000..1719a69053f --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/getting-started/languages-and-vms.md @@ -0,0 +1,84 @@ +import EVMCompatibility from '../_admonitions/_EVM_compatibility.md' + +# Supported Virtual Machines & Languages + +The current release of IOTA Smart Contracts has support for [EVM/Solidity](#evmsolidity-based-smart-contracts) smart +contracts, as well as experimental [Wasm](#wasm-vm-for-isc) smart contracts, providing compatibility with +existing smart contracts and tooling from other EVM based chains like Ethereum. This allows us to offer the existing +ecosystem around EVM/Solidity a familiar alternative. + +## EVM Smart Contracts + +### What is EVM/Solidity? + +[EVM](https://ethereum.org/en/developers/docs/evm/) stands for "Ethereum Virtual Machine" and is currently the tried and +tested virtual machine running most smart contract networks. + +[Solidity](https://soliditylang.org/) is the programming language of choice for the EVM. It was created for this +specific purpose. + +The main benefit of using EVM/Solidity is its sheer amount of resources from years of development. The IOTA +Smart Contracts implementation is fully compatible with all of them. If you have experience developing on other EVM based chains, you will feel right at home. Any existing contracts you've written will need no +changes to function on IOTA Smart Contracts. + +### How IOTA Smart Contracts Work With EVM + +Every deployed ISC chain automatically includes a core contract +called [`evm`](../reference/core-contracts/evm.md). This core contract is responsible for running EVM code and +storing the EVM state. + +The Wasp node also provides a standard JSON-RPC service, which allows you to interact with the EVM layer using existing +tooling like [MetaMask](https://metamask.io/), [Remix](https://remix.ethereum.org/) or [Hardhat](https://hardhat.org/). +Deploying EVM contracts is as easy as pointing your tools to the JSON-RPC endpoint. + + + +## Wasm VM for ISC + +:::warning Experimental + +The Wasm _VM_ is in experimental state, showcasing ISC's "VM plugin" architecture. + +Experiment but avoid using it for production applications; opt for [EVM](quick-start.mdx). + +::: + +IOTA Smart Contracts (ISC) provide a sandboxed environment through an API, facilitating secure and deterministic +interactions with ISC functions. This API supports any Virtual Machine (VM) aiming to build a system for smart contract + code execution on ISC. + +![Wasp node ISC Host](/img/wasm_vm/IscHost.png) + +You can use a [WebAssembly (Wasm)](https://webassembly.org/) VM as a compilation target, facilitated by the open-source +[Wasmtime runtime](https://wasmtime.dev/). This setup encourages dynamic smart contract operations compiled to Wasm code, +promoting security and adaptability with different programming languages. + +![Wasm VM](/img/wasm_vm/WasmVM.png) + +The Wasm VM operates with self-contained `WasmLib` libraries linked to individual Wasm codes, optimizing the ISC sandbox +functionality and smart contract state storage access. + +### Supported Functionalities + +The ISC sandbox environment offers: + +- Smart contract metadata and state data access. +- Request data retrieval for function calls. +- Token management within the contract. +- Utility functions from the host. +- Smooth initiation of other smart contract functions. +- Logging facility. + +### Supported Languages + +The WasmLib started with [Rust](https://www.rust-lang.org/) support, expanding to include [Go](https://golang.org/) +and [TypeScript](https://www.typescriptlang.org/) with the help of respective Wasm code generators: + +| Language | Wasm code generator | +|------------|----------------------------------------------------| +| Go | [TinyGo](https://tinygo.org/) | +| Rust | [wasm-pack](https://rustwasm.github.io/wasm-pack/) | +| TypeScript | [AssemblyScript](https://www.assemblyscript.org/) | + +These generators maintain a common subset of their host language, aiming for a unified coding style to simplify the +initiation into smart contract creation, welcoming developers with a C-style language background to quickly adapt. \ No newline at end of file diff --git a/docs/content/guides/developer/layer-2-smart-contracts/getting-started/networks-and-chains.mdx b/docs/content/guides/developer/layer-2-smart-contracts/getting-started/networks-and-chains.mdx new file mode 100644 index 00000000000..cc3796b00ed --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/getting-started/networks-and-chains.mdx @@ -0,0 +1,143 @@ +--- +description: Networks and endpoints in the IOTA ecosystem. +tags: + - mainnet + - shimmer + - devnet + - EVM Testnet + - reference + - Endpoints +--- +import { AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; +import { Networks } from '@theme/constant'; +import NetworkInfo from '@theme/NetworkInfo'; + +# Networks & Chains +## IOTA EVM Testnet + + + +[The IOTA EVM Testnet](https://explorer.evm.testnet.iotaledger.net/) runs as a layer 2 on top +of the [IOTA Testnet](/build/networks-endpoints#iota-testnet). This network uses ISC to facilitate +an Ethereum Virtual Machine and has an enshrined bridge to layer 1. + +:::info + +This network is subject to occasional resets (no data retention) which are usually announced with a one-week grace period. + +::: + + + +:::note + +The other values (network name and currency symbol) can be whatever value you like. + +::: + +## IOTA EVM + +[IOTA EVM](https://explorer.evm.iota.org) is the L2 EVM running on top of the IOTA network. + + + + + +### Additional Info + + + +## IOTA EVM Testnet + + + +[The IOTA EVM Testnet](https://explorer.evm.testnet.iotaledger.net/) runs as a layer 2 on top +of the [IOTA Testnet](/build/networks-endpoints#iota-testnet). This network uses ISC to facilitate + +:::info + +This network is subject to occasional resets (no data retention) which are usually announced with a one-week grace period. + +::: + + + +:::note + +The other values (network name and currency symbol) can be whatever value you like. + +::: + +### Additional Info + + + +## ShimmerEVM Testnet + + + +[The ShimmerEVM Testnet](https://explorer.evm.testnet.shimmer.network/) runs as a layer 2 on top +of the [Shimmer Testnet](/build/networks-endpoints#shimmer-testnet). This network uses ISC to facilitate +an Ethereum Virtual Machine and has an enshrined bridge to layer 1. + +:::info + +This network is subject to occasional resets (no data retention) which are usually announced with a one-week grace period. + +::: + + + +:::note + +The other values (network name and currency symbol) can be whatever value you like. + +::: + +### Additional Info + + + +## ShimmerEVM + +[ShimmerEVM](https://explorer.evm.shimmer.network/) is the L2 EVM running on top of the Shimmer network. + + + + + +### Additional Info + + + +## ShimmerEVM Testnet + + + +[The ShimmerEVM Testnet](https://explorer.evm.testnet.shimmer.network/) runs as a layer 2 on top +of the [Shimmer Testnet](/build/networks-endpoints#shimmer-testnet). This network uses ISC to facilitate +an Ethereum Virtual Machine and has an enshrined bridge to layer 1. + +:::info + +This network is subject to occasional resets (no data retention) which are usually announced with a one-week grace period. + +::: + + + +:::note + +The other values (network name and currency symbol) can be whatever value you like. + +::: + +### Additional Info + + + +## Core Contracts + +[IOTA EVM](#IOTAEVM), [ShimmerEVM](#shimmerEVM) and the testnet networks have 7 +[core contracts](../reference/core-contracts/overview.md) deployed, as well as the +[Magic Contract](../reference/magic-contract/introduction.md). diff --git a/docs/content/guides/developer/layer-2-smart-contracts/getting-started/quick-start.mdx b/docs/content/guides/developer/layer-2-smart-contracts/getting-started/quick-start.mdx new file mode 100644 index 00000000000..65b242366db --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/getting-started/quick-start.mdx @@ -0,0 +1,83 @@ +--- +description: This guide will help you quickly get started with the EVM +image: /img/logo/WASP_logo_dark.png +tags: + - quickstart + - developer + - using + - EVM + - Ethereum + - Solidity + - metamask + - JSON + - RPC +--- +import DeployAdmonition from '../_admonitions/_deploy_a_smart_contract.md'; +import MetamaskButtons from '../../../../_partials/_metamask_buttons.mdx'; +import { Networks } from '@theme/constant'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import Link from '@docusaurus/Link'; + +# EVM Quickstart Guide + +This guide will help you quickly get started with our EVM, where you can deploy and interact with EVM-compatible smart contracts. + +## Prerequisites + +- [MetaMask](https://metamask.io/) browser extension installed + +## Setup MetaMask + +Click this button: + + + +:::tip + +Please read [the MetaMask section in the tools guide](tools.mdx#metamask) for a detailed guide. + +::: + +## Deploy and Interact with Smart Contracts + +:::tip Fund your testnet account + +If you are using one of the testnets you can just use the the toolkit to get testnet tokens. + +1. Go to the [IOTA EVM](https://evm-toolkit.evm.testnet.iotaledger.net) or [ShimmerEVM](https://evm-toolkit.evm.testnet.shimmer.network/) Testnet Toolkit. +2. Connect your MetaMask wallet by clicking "Connect Wallet" or paste an EVM address. +3. Select the account you want to receive testnet tokens. +4. Click "Send funds" to get testnet tokens. + +::: + +You can now deploy and interact with smart contracts. Utilize popular development tools and frameworks, such as [Hardhat](https://hardhat.org/), or [Remix](https://remix.ethereum.org/), to build, test, and deploy your smart contracts. + + + +## Explore the Network + +Visit the corresponding Block Explorer to monitor the chain, track transactions, and explore deployed smart contracts. + + + +Explorer + + +Explorer + + +Explorer + + +Explorer + + + +## Additional Resources + +- [GitHub issues page for Wasp](https://github.com/iotaledger/wasp/issues) +- [Firefly](https://firefly.iota.org) + +With this quickstart guide, you should now be able to set up and start exploring the EVM. As you begin to deploy and interact with smart contracts, remember to provide feedback on any issues or improvements you discover to help make our EVM even better. Happy developing! diff --git a/docs/content/guides/developer/layer-2-smart-contracts/getting-started/tools.mdx b/docs/content/guides/developer/layer-2-smart-contracts/getting-started/tools.mdx new file mode 100644 index 00000000000..d2150465845 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/getting-started/tools.mdx @@ -0,0 +1,189 @@ +--- +description: 'Existing EVM tooling is compatible and can be used directly with an IOTA Smart Contracts chain running EVM. +You can configure hardhat, metamask, remix, Ether.js and Web3.js among others.' +image: /img/logo/WASP_logo_dark.png +tags: + +- smart contracts +- chain +- EVM +- Solidity +- tooling +- wasp-cli +- hardhat +- metamask +- JSON-RPC +- reference + +--- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import {AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; +import HardhatConfig from '../_partials/_hardhat_config.md'; +import { Networks } from '@theme/constant'; +import DeployAdmonition from '../_admonitions/_deploy_a_smart_contract.md'; +import { ChainId } from '@theme/ChainId'; +import NetworkInfo from '@theme/NetworkInfo'; +import OraclesContractData from '../../../../_partials/_oracles_contract_data.md'; + +# Compatible Tools + +EVM on IOTA Smart Contracts has been integrated in a way that the existing EVM tooling is compatible and can be used +directly with an IOTA Smart Contracts chain running EVM as long as you take a couple of things into account. + +## Tooling Considerations + +1. Please make sure you use the correct JSON-RPC endpoint URL in your tooling for your chain. If you're running your own chain, you can find the JSON-RPC +endpoint URL in the Wasp dashboard (`[URL]/wasp/dashboard` when using `node-docker-setup`). +2. Please ensure you use the correct `Chain ID` configured while starting the JSON-RPC service. If you did not explicitly define this while starting the service, the default Chain ID will be +for IOTA EVM, +for ShimmerEVM or for the EVM Testnet. +3. Fees are handled on the IOTA Smart Contracts chain level, not the EVM level. The chain will reject any requests with a different gas price than specified by the chain. + +:::caution + +Re-using an existing Chain ID is not recommended and can be a security risk. For production usage, register a unique Chain +ID on [Chainlist](https://chainlist.org/) and use that instead of the default. **It is not possible to change the EVM +chain ID after deployment.** + +::: + +## Network RPCs + + + + + + + + + + + + + + + + + + + + +## IOTA EVM Tools + +The following tools are **only available on IOTA EVM**. + +### Blast API + +The [Blast API](/build/blastAPI) is a decentralized platform that provides reliable and scalable node infrastructure +for accessing blockchain data. You can find the Blast API URLs in the [Network RPCs](#network-rpcs) + +### EVM Toolkit + +You can use the [IOTA EVM Toolkit](https://evm-toolkit.evm.iotaledger.net) to withdraw assets from IOTA EVM to IOTA L1. +It also includes a wrapper IOTA <-> wIOTA. + +### Multicall3 + +If you need to aggregate results from multiple contract reads into a single JSON-RPC request or execute multiple +state-changing calls in a single transaction, you can use the [Multicall3 contract](https://explorer.evm.iota.org/address/0xcA11bde05977b3631167028862bE2a173976CA11?tab=contract). + +## IOTA EVM and ShimmerEVM Tools + +The following tools are available on both IOTA EVM end ShimmerEVM. + +### MultiSig Wallets + +If you require and additional level of security, you can use the [Safe{} Wallet](https://safe.iotaledger.net/) as a +Multisig solution on IOTA EVM. + +### Oracles + +If your project requires [Oracles](/build/oracles/) to provide data from the outside world, you find both Pyth and Supra have integrated IOTA EVM. + + + +### Subgraphs + +[Subgraphs](/build/subgraphs/) provide a streamlined way for developers to access blockchain data relevant to their applications, +significantly enhancing developer efficiency and user experience. IOTA EVM subgraphs available via [Goldsky](https://goldsky.com). + +## MetaMask + +[MetaMask](https://metamask.io/) is a popular EVM wallet which runs in a browser extension that allows you to +interact with EVM chains and their applications (dApps). + +To use your EVM chain with MetaMask, simply open up MetaMask and click on the network drop-down list at the very top. At +the bottom of this list, you will see the option `Add network`. On the new page you will see a list of popular network with the option `Add a network manually`. +For example this would be the configs to add our different [EVM chains](/build/networks-endpoints): + + + + + + + + + + + + + + + + + + + + +Ensure that your `RPC Url` and `Chain ID` are set correctly and match the dashboard values. The `Network Name` can be +whatever you see fit. Click "Save" to add the chain to MetaMask. + +If you wish to use additional EVM chains with Metamask, you can add more Custom RPC networks, as long as they have a +unique `Chain ID` and `RPC Url`. Once you have done this, you can start using MetaMask to manage your EVM wallet or +issue/sign transactions with any dApp running on that network. + +### Remix + +If you also want to use the [Remix IDE](https://remix.ethereum.org/) to deploy any regular Solidity Smart Contract, you +should set the environment as **Injected Provider - Metamask**, which should then connect with your MetaMask wallet. + +Click on the _Deploy & Run transactions_ button in the menu on the left and select `Injected Web3` from +the `Environment` dropdown. + +![Select Injected Provider from the Environment dropdown](/img/evm/remix-injected-provider-metamask.png) + + + +Metamask will ask to connect to Remix, and once connected, it will set the `Environment` to `Injected Web3` with +the "Custom (Chain ID) network". + +![Environment will be set to Injected Web3](/img/evm/remix-injected-provider-set.png)] + +## Hardhat + +[Hardhat](https://hardhat.org/) is a command line toolbox that allows you to deploy, test, verify, and interact with +Solidity smart contracts on an EVM chain. EVM chains running on IOTA Smart Contracts are compatible with Hardhat; simply +make sure you add the correct network parameters to your `hardhat.config.js`, for example: + + + + + +:::caution + +Currently, there is no validation service available for EVM/Solidity smart contracts on IOTA Smart Contracts, which is +often offered through block explorer APIs. + +::: + +## Ethers.js/Web3.js + +If you input the correct configuration parameters for the JSON-RPC endpoint to talk to, +[Ethers.js](https://docs.ethers.io/) and [Web3.js](https://web3js.readthedocs.io/) are also compatible with EVM chains on IOTA Smart Contracts. +Alternatively, you can let both interact through MetaMask instead so that it uses the +network configured in MetaMask. For more information on this, read their documentation. + +## Other Tooling + +Most tools available will be compatible if you enter the correct `Chain ID` and `RPC Url`. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/ERC20.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/ERC20.md new file mode 100644 index 00000000000..adf0a6ccfa1 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/ERC20.md @@ -0,0 +1,94 @@ +--- +description: Solidity smart contract ERC20. +image: /img/logo/WASP_logo_dark.png +tags: + - smart contracts + - EVM + - Solidity + - ERC20 + - eip-20 + - token creation + - mint tokens + - how to +--- + +import DeployAdmonition from '../_admonitions/_deploy_a_smart_contract.md'; +import PriorKnowledge from '../_admonitions/_EVM-required-prior-knowledge.md'; +import RemixIDE from '../_admonitions/_remix-IDE.md'; + +# Create ERC20 Custom Tokens + +## Required Prior Knowledge + + + +## About ERC20 + +ERC20 is a standard for fungible tokens and is defined in +the [EIP-20 Token Standard](https://eips.ethereum.org/EIPS/eip-20) by Ethereum. + +With the ERC20 standard, you can create your own tokens and transfer them to the EVM on IOTA Smart Contracts without +fees. + + + +## 1. Create the Smart Contract + +Create a new Solidity file, for example, `ERC20.sol` in the contracts folder of +your [Remix IDE](https://remix.ethereum.org/) and add this code snippet: + +```solidity +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.7; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract ExampleERC20Token is ERC20 { + constructor() ERC20("ExampleERC20Token", "EET") { + _mint(msg.sender, 1000000 * 10 ** decimals()); + } +} +``` + +This imports all functions from the [OpenZeppelin ERC20](https://docs.openzeppelin.com/contracts/4.x/erc20) smart +contract and creates a new ERC20 token with your name and Symbol. + +:::tip OpenZeppelin + +OpenZeppelin provides many audited smart contracts and is a good point to start and learn. + +::: + +:::note Customize Your Token + +You can change the token name `ExampleERC20Token` and the token symbol `EET` for anything you want. + +::: + + + +## 2. Add Your Custom Tokens to MetaMask + +Once you have deployed your contract, you can add your new custom token to your Metamask account. + +1. Open Metamask, and click on the transaction that created the contract. From there, you can simply click + on `View on block explorer` to visit the transaction details. Alternatively, you can copy the transaction ID and + visit the [IOTA EVM Explorer](https://explorer.evm.iota.org), + [ShimmerEVM Explorer](https://explorer.evm.testnet.shimmer.network/) + or [EVM Testnet Explorer](https://explorer.evm.testnet.shimmer.network/) and use the search bar to find transaction. + +!['View on block explorer](/img/evm/how-tos/ERC20/metamask-get-transaction-or-go-to-block-explorer.png) + +2. Copy the contract address from the transaction details, and import your custom ERC20 tokens into MetaMask. + +![Copy contract address](/img/evm/how-tos/ERC20/metamask-import-tokens.png) + +## 3. Have some Fun + +Now you should see your token in MetaMask. You can send them to your friends without any fees or gas costs. + +![Copy contract address](/img/evm/how-tos/ERC20/metamask-erc20-balance.png) + +You also can ask in the [Discord Chat Server](https://discord.iota.org) to send them around and discover what the +community is building on IOTA Smart Contracts. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/ERC721.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/ERC721.md new file mode 100644 index 00000000000..767661dbff2 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/ERC721.md @@ -0,0 +1,129 @@ +--- +description: Create and deploy a Solidity smart contract to mint NFTs using the ERC721 standard. +image: /img/evm/ozw-721.png +tags: + - smart contracts + - EVM + - Solidity + - ERC721 + - eip-721 + - token creation + - mint tokens + - how to +--- +import DeployAdmonition from '../_admonitions/_deploy_a_smart_contract.md'; +import PriorKnowledge from '../_admonitions/_EVM-required-prior-knowledge.md'; +import RemixIDE from '../_admonitions/_remix-IDE.md'; + +# Create ERC721 NFTs + +:::info EVM-only NFT + +Please keep in mind that this is an EVM-only NFT. It's not tied to L1 native assets. Also, these are different from L1 +NFTs. + +::: + + + +## About ERC721 + +Non-fungible tokens or NFTs are a type of token that can represent any unique object, including a real-world asset on a +decentralized network. NFTs are commonly represented by the ([ERC721 standard](https://eips.ethereum.org/EIPS/eip-721)). +You can use the +openzepplin +lib [`@openzeppelin/contracts/token/ERC721/ERC721.sol`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol) +to streamline your development experience. + +You can also use the ([OpenZepplin Contracts Wizard](https://wizard.openzeppelin.com/#erc721)) to generate and customize +your smart contracts. + + + +## Create the Smart Contract + +The following is an example NFT Smart Contract called "IotaEVMSampleNFT". + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import "@openzeppelin/contracts@5.0.1/token/ERC721/ERC721.sol"; +import "@openzeppelin/contracts@5.0.1/access/Ownable.sol"; + +contract IotaEVMSampleNFT is ERC721, Ownable { + uint256 private _nextTokenId; + + constructor(address initialOwner) + ERC721("IotaEVMSampleNFT", "SSNFT") + Ownable(initialOwner) + {} + + function _baseURI() internal pure override returns (string memory) { + return "https://example.com/nft/"; + } + + function safeMint(address to) public onlyOwner { + uint256 tokenId = _nextTokenId++; + _safeMint(to, tokenId); + } +} +``` + +As you can see above, the contract uses standard methods for the most part. You should pay attention to the following: + +- `pragma solidity ^0.8.20;`: This line means the contract uses solidity compiler version `0.8.20` or above. +- `contract IotaEVMSampleNFT is ERC721, ERC721URIStorage, Ownable`: This line defines the contract's name, and what + other contracts it implements. +- `ERC721("IotaEVMSampleNFT", "SNFT") {}`: This line defines the token name and symbol. You can name it + whatever you want. We recommend using the same name for the token and the contract. +- `return "https://example.com/nft/";`: You should define the base URI of your NFTs. That means the URL you provide here + will be used for all your tokens. Since this contract uses auto-incremental token IDs, your token URI will look + something like `https://example.com/nft/0`, `https://example.com/nft/1`, `https://example.com/nft/2`, and so on. +- `function safeMint(address to, string memory uri) public onlyOwner {`: The `safeMint` function will + require that you manually input a token's `to` address and a `uri` every time you want to mint. This should work for + regular use cases. + +### Customize on OpenZeppelin + +You can customize your contract depending on how you want it to behave. You should consider the following topics +and questions: + +1. **Ownership** — Who owns it? How is it stored? +2. **Creation** — Method or Type of Creation. +3. **Transfer & Allowance** — How will tokens be transferred? How will they be available to other addresses and + accounts? +4. **Burn** — Do you want to destroy it? If yes, how? + +You can click on `Copy to Clipboard` and paste it into the IDE of your choice, download it, or click on `Open in Remix` +directly. + + +:::note Set the Initial Owner + +Before you can deploy this contract, you will need to set the `Initial Owner` address; this can be your own IOTA EVM address. + +!["Set the initial owner" img.png](/img/evm/how-tos/ERC721/set-initial-owner.png) + +::: + + + +### Mint Your Custom NFTs + +So far, you have [created](#create-the-smart-contract) and deployed the contract. But, you probably want to mint some NFTs. +To do, you should: + +1. Open the contract (listed under `Deployed Contracts`). +2. Insert your target IOTA EVM in beside the `safeMint` button and then click the button. + + ![Safe mint](/img/evm/how-tos/ERC721/safe-mint.png) + +3. Confirm the transaction on Metamask. + + ![Confirm in metamask](/img/evm/how-tos/ERC721/confirm-in-metamask.png) + +If you visit your address in the visit the [IOTA EVM Explorer](https://explorer.evm.iota.org), +[ShimmerEVM Explorer](https://explorer.evm.testnet.shimmer.network/) or [EVM Testnet Explorer](https://explorer.evm.testnet.shimmer.network/) +you should see your NFTs listed under `Tokens`. + diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/allow.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/allow.md new file mode 100644 index 00000000000..edf7027f439 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/allow.md @@ -0,0 +1,64 @@ +--- +description: How to allow native assets and base token +image: /img/logo/WASP_logo_dark.png +tags: + - allow + - allowance + - EVM + - magic + - solidity +--- + +# Allow + +The allowance concept is well known from the EVM contracts like ERC20. +In ISC, we have a similar concept for our native assets. You might want to use this, for example, to [send native assets to L1](../send-assets-to-l1.mdx) (which includes sending tokens to other L1 chain accounts). + +## Example Code + +### 1. Create the `allow` Function + +Create a function which allows an address or contract to access a specific ID of your account: + +```solidity +function allow(address _address, bytes32 _allowanceNFTID) public { +``` + +### 2. Create the `ISCAssets` object + +Create an `ISCAssets` object to pass as allowance: + +```solidity +NFTID[] memory nftIDs = new NFTID[](1); +nftIDs[0] = NFTID.wrap(_allowanceNFTID); +ISCAssets memory assets; +assets.nfts = nftIDs; +``` + +### 3. Use the Assets as Allowance + +With that asset, you can call `allow` to allow address to take our NFT: + +```solidity +ISC.sandbox.allow(_address, assets); +``` + +## Full Example Code + +```solidity +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "@iota/iscmagic/ISC.sol"; + +contract Allowance { + function allow(address _address, bytes32 _allowanceNFTID) public { + NFTID[] memory nftIDs = new NFTID[](1); + nftIDs[0] = NFTID.wrap(_allowanceNFTID); + ISCAssets memory assets; + assets.nfts = nftIDs; + ISC.sandbox.allow(_address, assets); + } +} +``` diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/get-allowance.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/get-allowance.md new file mode 100644 index 00000000000..353df44011c --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/get-allowance.md @@ -0,0 +1,79 @@ +--- +description: How to get the allowance of native assets and base token +image: /img/logo/WASP_logo_dark.png +tags: + - allowance + - EVM + - magic + - solidity +--- + +# Get Allowance + +## Example Code + +There are multiple ways to check for an allowance. + +### `getAllowanceFrom()` + +`getAllowanceFrom()` fetches the funds currently allowed by the given address to the caller: + +```soliditiy +function getAllowanceFrom(address _address) public { + ISCAssets assets = ISC.sandbox.getAllowanceFrom(_address); + emit AllowanceFrom(assets) +} +``` + +### `getAllowanceTo()` + +`getAllowanceTo()` fetches the funds currently allowed by the caller to the given address: + +```soliditiy +function getAllowanceTo(address _target) public { + ISCAssets assets = ISC.sandbox.getAllowanceTo(_target); + emit AllowanceTo(assets) +} +``` + +### `getAllowance()` + +`getAllowance()` gets the funds currently allowed between the given addresses: + +```soliditiy +function getAllowance(address _from, address _to) public { + ISCAssets assets = ISC.sandbox.getAllowance(_from, _to); + emit Allowance(assets) +} +``` + +## Full Example Code + +```solidity +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "@iota/iscmagic/ISC.sol"; + +contract allowance { + event AllowanceFrom(ISCAssets assets) + event AllowanceTo(ISCAssets assets) + event Allowance(ISCAssets assets) + + function getAllowanceFrom(address _address) public { + ISCAssets assets = ISC.sandbox.getAllowanceFrom(_address); + emit AllowanceFrom(assets) + } + + function getAllowanceTo(address _target) public { + ISCAssets assets = ISC.sandbox.getAllowanceTo(_target); + emit AllowanceTo(assets) + } + + function getAllowance(address _from, address _to) public { + ISCAssets assets = ISC.sandbox.getAllowance(_from, _to); + emit Allowance(assets) + } +} +``` diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/take-allowance.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/take-allowance.md new file mode 100644 index 00000000000..b41689fb898 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/take-allowance.md @@ -0,0 +1,56 @@ +--- +description: How to take the allowance of native assets and base token +image: /img/logo/WASP_logo_dark.png +tags: + - allowance + - EVM + - magic + - solidity +--- + +# Take allowed Funds + +After having [allowed](./allow.md) native assets, you can take the ones you need. + +## Example Code + +The following example will take the NFT which was allowed in the [allow how-to guide](./allow.md). + +### Create the `ISCAssets` + +First, you need to recreate the `ISCAssets` with the NFTID. + +```solidity +NFTID[] memory nftIDs = new NFTID[](1); +nftIDs[0] = NFTID.wrap(_allowanceNFTID); +ISCAssets memory assets; +assets.nfts = nftIDs; +``` + +### Call `takeAllowedFunds()` + +After that, you can call `takeAllowedFunds()` to take the allowance of the specified address/contract + +```solidity +ISC.sandbox.takeAllowedFunds(_address, NFTID); +``` + +## Full Example Code + +```solidity +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "@iota/iscmagic/ISC.sol"; + +contract allowance { + function takeAllowedFunds(address _address, bytes32 NFTID) { + NFTID[] memory nftIDs = new NFTID[](1); + nftIDs[0] = NFTID.wrap(_allowanceNFTID); + ISCAssets memory assets; + assets.nfts = nftIDs; + ISC.sandbox.takeAllowedFunds(_address, NFTID); + } +} +``` diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/get-balance.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/get-balance.md new file mode 100644 index 00000000000..aa25f559ac0 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/get-balance.md @@ -0,0 +1,74 @@ +--- +description: How to get the balance of L1 assets on L2 +image: /img/logo/WASP_logo_dark.png +tags: + - native assets + - balance + - EVM + - how-to +--- + +# Get Balance + +Once you have your L1 assets on L2, you might want to check their balance. This guide explains how to do so by calling the three functions `getL2BalanceBaseTokens`, `getL2BalanceNativeTokens`and `getL2NFTAmount` for the corresponding token types. + + +## Example Code + +1. Get the [AgentID](../../../explanations/how-accounts-work.md) from the sender by calling `ISC.sandbox.getSenderAccount()`. + +```solidity +ISCAgentID memory agentID = ISC.sandbox.getSenderAccount(); +``` + +2. To get the base token balance, you can call `getL2BalanceBaseTokens` using the `agentID`. + +```solidity +uint64 baseBalance = ISC.accounts.getL2BalanceBaseTokens(agentID); +``` + +3. To get the native token balance of a specific `NativeTokenID`, use `ISC.accounts.getL2BalanceNativeTokens` with the `id` and `agentID`. + +```solidity +NativeTokenID memory id = NativeTokenID({ data: nativeTokenID}); +uint256 nativeTokens = ISC.accounts.getL2BalanceNativeTokens(id, agentID); +``` + +4. To get the number of NFTs, use `ISC.accounts.getL2NFTAmount` with the `agentID`. + +```solidity +uint256 nfts = ISC.accounts.getL2NFTAmount(agentID); +``` + +### Full Example Code + +```solidity +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "@iota/iscmagic/ISC.sol"; + +contract GetBalance { + event GotAgentID(bytes agentID); + event GotBaseBalance(uint64 baseBalance); + event GotNativeTokenBalance(uint256 nativeTokenBalance); + event GotNFTIDs(uint256 nftBalance); + + function getBalance(bytes memory nativeTokenID) public { + ISCAgentID memory agentID = ISC.sandbox.getSenderAccount(); + emit GotAgentID(agentID.data); + + uint64 baseBalance = ISC.accounts.getL2BalanceBaseTokens(agentID); + emit GotBaseBalance(baseBalance); + + NativeTokenID memory id = NativeTokenID({ data: nativeTokenID}); + uint256 nativeTokens = ISC.accounts.getL2BalanceNativeTokens(id, agentID); + emit GotNativeTokenBalance(nativeTokens); + + uint256 nfts = ISC.accounts.getL2NFTAmount(agentID); + emit GotNativeTokenBalance(nfts); + } +} +``` + diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/send-assets-to-l1.mdx b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/send-assets-to-l1.mdx new file mode 100644 index 00000000000..a479d9bb2c1 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/send-assets-to-l1.mdx @@ -0,0 +1,70 @@ +--- +description: The ISC Magic Contract allows EVM contracts to access ISC functionality. +image: /img/logo/WASP_logo_dark.png +tags: + - configure + - using + - EVM + - magic + - Ethereum + - Solidity +--- + +import AboutAccounts from '../../../_admonitions/_about-accounts.md'; + +# Send Assets and Tokens to L1 + + + +:::info + +IOTA EVM and ShimmerEVM have 18 decimal places, while IOTA and Shimmer have 6. This means that any decimals beyond the 6th will be ignored by IOTA and Shimmer, even though you can see them on IOTA EVM and ShimmerEVM. Please keep this in mind while sending your tokens to L1. + +::: + +This guide will show you how to use the ISC sandbox interface to send assets from L2 to L1. This includes base tokens, native tokens, and NFTs. Before you can send these assets, you need to know how you get them on L2 and how you allow a contract to use them. + +Note that assets on L1 require a storage deposit; therefore, the number of base tokens sent to L1 should cover at least the storage deposit required to hold the assets on L1. + +## Explanation + +First, you will find out what assets this contract is allowed to take from the caller by calling the `ISC.sandbox.getAllowanceFrom()` function. + +```solidity +ISCAssets memory allowance = ISC.sandbox.getAllowanceFrom(msg.sender); +``` + +Then you take the allowance, which will transfer the assets from the caller to the contract. + +```solidity +ISC.sandbox.takeAllowedFunds(msg.sender, allowance); +``` + +Finally, you can send the assets to the specified L1 address. This will create an output to hold said assets. You can use additional options to add the [timelock](/learn/protocols/stardust/core-concepts/output-unlock-conditions/#timelock) and [expiration](/learn/protocols/stardust/core-concepts/output-unlock-conditions/#expiration) unlock conditions to the output. + +```solidity +ISCSendMetadata memory metadata; +ISCSendOptions memory options; +ISC.sandbox.send(to, allowance, false, metadata, options); +``` + +## Full Example Code + +```solidity +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "@iota/iscmagic/ISC.sol"; + +contract L1Assets { + function withdraw(L1Address memory to) public { + ISCAssets memory allowance = ISC.sandbox.getAllowanceFrom(msg.sender); + ISC.sandbox.takeAllowedFunds(msg.sender, allowance); + + ISCSendMetadata memory metadata; + ISCSendOptions memory options; + ISC.sandbox.send(to, allowance, false, metadata, options); + } +} +``` \ No newline at end of file diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/call-view.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/call-view.md new file mode 100644 index 00000000000..d66fe7c9726 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/call-view.md @@ -0,0 +1,96 @@ +--- +description: With call and callView you can interact with any core contract +image: /img/logo/WASP_logo_dark.png +tags: + - magic contract + - core + - EVM + - Ethereum + - Solidity + - ISC +--- + +# Interact with any Core contract + +## About `call` and `callView` + +The magic contract provides you with a solidity interface to the core contracts. Some functions like [`getL2BalanceBaseTokens`](../../reference/magic-contract/ISCAccounts.md#getl2balancebasetokens) are wrapped in the magic contract directly, others you need to call yourself. You can do that with the [`call`](../../reference/magic-contract/ISCSandbox.md#call) and [`callView`](../../reference/magic-contract/ISCSandbox.md#callview) functions. + +:::info WASM + +You can also use `call` and `callView` to interact with WASM contracts. + +::: + +## Example Code + +1. Get the [`AgentID`](../../explanations/how-accounts-work.md) from the sender by calling ISC.sandbox.getSenderAccount(). + +```solidity +ISCAgentID memory agentID = ISC.sandbox.getSenderAccount(); +``` + +2. Initialize the parameters for the call by creating a new [`ISCDict`](../../reference/magic-contract/ISCTypes.md#iscdict). As you can see in the docs, [`getl2balancenativetokens`](../../reference/magic-contract/ISCAccounts.md#getl2balancenativetokens) takes two parameters.: the Agent ID and the native token ID. So, you have to create a dictionary with two key-value pairs. The key of the first pair (Agent ID) has to be `a` and the key for the second pair (native token ID) `N`. + +```solidity +ISCDict memory params = ISCDict(new ISCDictItem[](2)); +params.items[0] = ISCDictItem("a", agentID.data); +params.items[1] = ISCDictItem("N", nativeTokenID); +``` + +3. Now, you can use [`callView`](../../reference/magic-contract/ISCSandbox.md#callview) to call our contract. The first parameter is the core contract `hname`, which we can get with the helper utility [`hn`](../../reference/magic-contract/ISCUtil.md#hn), and the second parameter is the function we want to call. The last parameter is the dictionary with all function parameters. + +```solidity +ISCDict memory result = ISC.sandbox.callView( + ISC.util.hn("accounts"), + ISC.util.hn("balanceNativeToken"), + params +); +``` + +4. Next, you can either return or emit the result. + +```solidity +emit NativeTokenBalance(bytesToUint(result.items[0].value)); +``` + +:::info Return Dictionary + +Keep in mind that the call and callView functions will always return a dictionary. The values of this dictionary are always of type byte, so you need to take care of converting it yourself. + +::: + +### Full Example Code + +```solidity +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "@iota/iscmagic/ISC.sol"; + +contract NativeTokenBalance { + event NativeTokenBalance(uint balance); + + function getNativeTokenBalance(bytes memory nativeTokenID) public { + ISCAgentID memory agentID = ISC.sandbox.getSenderAccount(); + + ISCDict memory params = ISCDict(new ISCDictItem[](2)); + params.items[0] = ISCDictItem("a", agentID.data); + params.items[1] = ISCDictItem("N", nativeTokenID); + + ISCDict memory result = ISC.sandbox.callView( + ISC.util.hn("accounts"), + ISC.util.hn("balanceNativeToken"), + params + ); + + emit NativeTokenBalance(bytesToUint(result.items[0].value)); + } + + function bytesToUint(bytes memory b) internal pure virtual returns (uint256) { + require(b.length <= 32, "Bytes length exceeds 32."); + return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256)); + } +} +``` diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/get-randomness-on-l2.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/get-randomness-on-l2.md new file mode 100644 index 00000000000..3bf4b3b35e1 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/get-randomness-on-l2.md @@ -0,0 +1,127 @@ +--- +description: You can use the ISC Magic Contract in EVM contracts to access ISC functionality, such as randomness. +image: /img/logo/WASP_logo_dark.png +tags: + - magic contract + - randomness + - EVM + - Ethereum + - Solidity + - ISC +--- + +# Get Randomness on L2 + +ISC introduces a feature not found on many other smart contract protocols: randomness. + +In the ISC protocol, for each state update, each validator proposes a batch of smart contract requests that they would like to process next. They commit to their proposals with a signature, after which a common subset of requests is found, and a combined signature is produced. + +This combined signature is unpredictable, and not only serves as protection against MEV by pseudo-randomly ordering requests, but also provides a source of verifiable entropy for randomness on L2. + +This guide will show you how you can use this entropy to generate random values in your contracts. + +:::info A note about entropy + +While entropy is random for each smart contract request, entropy is constant within a request. This means multiple calls to get entropy within the same request will return the same value. + +::: + +## Explanation + +When you want to generate multiple random values within a single request, you need to take into account that entropy is constant within a request. In this contract we use an increasing nonce in addition to the entropy, to make sure we are generating unique values: + +```solidity +uint256 private _nonce; + +function getNonce() internal returns (bytes32) { + return bytes32(_nonce++); +} +``` + +### Generating Integers + +To then generate a random integer, you can take the entropy and a unique nonce and hash them together: + +```solidity +bytes32 entropy = ISC.sandbox.getEntropy(); +bytes32 nonce = getNonce(); +bytes32 digest = keccak256(bytes.concat(entropy, nonce)); +``` + +And then cast the digest to an integer: + +```solidity +uint256 value = uint256(digest); +``` + +### Generating bytes + +Similarly to generating a random integer, you can generate any sequence of random bytes by taking the entropy and a unique nonce and hash them together: + +```solidity +bytes32 entropy = ISC.sandbox.getEntropy(); +bytes32 nonce = getNonce(); +bytes32 digest = keccak256(bytes.concat(entropy, nonce)); +``` + +And then repeatidly hash the digest and copy it in a sequence of bytes until you reach the required length. + +```solidity +bytes memory value = new bytes(length); +for (uint i = 0; i < length; i += 32) { + digest = keccak256(bytes.concat(digest)); + for (uint j = 0; j < 32 && i + j < length; j++) { + value[i + j] = digest[j]; + } +} +``` + +## Full Example Code + +```solidity +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "@iota/iscmagic/ISC.sol"; + +contract Random { + event Int(uint256); + event Bytes(bytes); + + uint256 private _nonce; + + function getNonce() internal returns (bytes32) { + return bytes32(_nonce++); + } + + function getInt() public returns (uint256) { + bytes32 entropy = ISC.sandbox.getEntropy(); + bytes32 nonce = getNonce(); + bytes32 digest = keccak256(bytes.concat(entropy, nonce)); + + uint256 value = uint256(digest); + + emit Int(value); + return value; + } + + function getBytes(uint length) public returns (bytes memory) { + bytes32 entropy = ISC.sandbox.getEntropy(); + bytes32 nonce = getNonce(); + bytes32 digest = keccak256(bytes.concat(entropy, nonce)); + + bytes memory value = new bytes(length); + for (uint i = 0; i < length; i += 32) { + digest = keccak256(bytes.concat(digest)); + for (uint j = 0; j < 32 && i + j < length; j++) { + value[i + j] = digest[j]; + } + } + + emit Bytes(value); + return value; + } +} + +``` \ No newline at end of file diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/introduction.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/introduction.md new file mode 100644 index 00000000000..d8983b4e246 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/introduction.md @@ -0,0 +1,79 @@ +--- +description: The ISC Core Contracts allows VMs to access ISC functionality. +image: /img/logo/WASP_logo_dark.png +tags: + - configure + - using + - EVM + - magic + - Ethereum + - Solidity + - metamask + - JSON + - RPC +--- + +# The Core Contracts + +The [core contracs](../../explanations/core-contracts.md) are contracts deployed on every chain and are vital to interact with L1 and the chain itself. They can be called in Solidity through the [ISC Magic Contract](../../reference/magic-contract/introduction.md). + +## The ISC Magic Contract + +The Magic contract is an EVM contract deployed by default on every ISC chain, in the EVM genesis block, at +address `0x1074000000000000000000000000000000000000`. +The implementation of the Magic contract is baked-in in +the [`evm`](../../reference/core-contracts/evm.md) [core contract](../../reference/core-contracts/overview.md); +i.e. it is not a pure-Solidity contract. + +The Magic contract has several methods, which are categorized into specialized +interfaces: `ISCSandbox`, `ISCAccounts`, `ISCUtil` and so on. +You can access these interfaces from any Solidity contract by importing +the [ISC library](https://www.npmjs.com/package/@iota/iscmagic): + +```bash npm2yarn +npm install @iota/iscmagic +``` + +You can import it into your contracts like this: + +```solidity +import "@iota/iscmagic/ISC.sol"; +``` + +The Magic contract also provides proxy ERC20 contracts to manipulate ISC base +tokens and native tokens on L2. + +:::info Reference Docs + +If you need further info about magic contracts interfaces you can check out the [magic contract docs](../../reference/magic-contract/introduction.md). + +::: + +## Call a Function + +:::info Ease of use + +To make it easier for developers to use the core contracts, you should, in most cases, run the functions from the magic contract directly. For example, to get the native token balance, you could [call the `balanceNativeToken()`](./call-view.md) directly with `callView`, or use [`getl2balancenativetokens`](./basics/get-balance.md) of the magic contract, or (the suggested way) register your native token as [`ERC20`](../../reference/magic-contract/ERC20NativeTokens.md) and call the standard [`balanceof`](../../reference/magic-contract/ERC20NativeTokens.md#balanceof) function. What you use also depends on what you optimize for. For example, to save gas, it could be interesting for you to call core contracts from your favorite web3 library directly and compute other things off-chain. + +::: + +In the example below, `ISC.sandbox.getEntropy()` calls the +[`getEntropy`](https://github.com/iotaledger/wasp/blob/develop/packages/vm/core/evm/iscmagic/ISCSandbox.sol#L20) +method of the `ISCSandbox` interface, which, in turn, +calls [ISC Sandbox's](../../explanations/sandbox.md) `GetEntropy`. + +```solidity +pragma solidity >=0.8.5; + +import "@iota/iscmagic/ISC.sol"; + +contract MyEVMContract { + event EntropyEvent(bytes32 entropy); + + // this will emit a "random" value taken from the ISC entropy value + function emitEntropy() public { + bytes32 e = ISC.sandbox.getEntropy(); + emit EntropyEvent(e); + } +} +``` diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/introduction.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/introduction.md new file mode 100644 index 00000000000..506f0dfef13 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/introduction.md @@ -0,0 +1,17 @@ +--- +description: How to handle native NFTs on L2 and use them as ERC721 +image: /img/logo/WASP_logo_dark.png +tags: + - native + - NFT + - EVM + - how-to +--- +import DocCardList from '@theme/DocCardList'; + +# Native NFT and ERC721 + +The IOTA L1 can create NFTs, also called native NFTs. To use these NFTs on L2, you have +an ERC20 contract called `ERC721NFTs`, which contains all L1 NFTs owned by the chain. The following guides will show you how to [mint your own L1 NFT from L2](./mint-nft.md) and [use](./use-as-erc721.md) it with the `ERC721NFTs` contract. + + \ No newline at end of file diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/mint-nft.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/mint-nft.md new file mode 100644 index 00000000000..d889d7972a2 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/mint-nft.md @@ -0,0 +1,152 @@ +--- +description: How to mint L1 NFT +image: /img/logo/WASP_logo_dark.png +tags: + - NFT + - EVM + - how-to +--- +import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.md'; + +# Mint an NFT +## About NFTs + +The Stardust update allows you to create your own NFTs. You can also use [IRC27](/tips/tips/TIP-0027) for NFTs. This guide will show you how to create an IRC27 L1 NFT using a L2 smart contract. + +## Example Code + + + +2. Get the senders AgentID: + +```solidity +ISCAgentID memory agentID = ISC.sandbox.getSenderAccount(); +``` + +3. Create an `IRC27Metadata` struct with all the needed data: + +```solidity +IRC27NFTMetadata memory metadata = IRC27NFTMetadata({ + standard: "IRC27", + version: "v1.0", + mimeType: _mimeType, + uri: _uri, + name: _name +}); +``` + +4. Create all the data for the core contract call. To do so, you should create a new `ISCDict` with 2 parameters like specified in the reference docs for [`mintNFT`](../../../reference/core-contracts/accounts.md#mintnfti-immutabledata-a-agentid-c-collectionid-w-withdrawonmint) +* `I` is the immutable metadata we fill with the IRC27 metadata and +* `a` is the AgendID of the owner of the NFT + +```solidity +ISCDict memory params = ISCDict(new ISCDictItem[](2)); +params.items[0] = ISCDictItem("I", bytes(IRC27NFTMetadataToString(metadata))); +params.items[1] = ISCDictItem("a", agentID.data); +``` + +:::info IRC27NFTMetadataToString + +The full example below calls the `IRC27NFTMetadataToString` function, which simply converts the IRC27Metadata struct into a string. + +::: + +5. Call the magic contract `call` function with all the parameters. You should specify the core contract you want to call, which in this case is the [`account`](../../../reference/core-contracts/accounts.md) contract, and the function for [minting an NFT](../../../reference/core-contracts/accounts.md#mintnfti-immutabledata-a-agentid-c-collectionid-w-withdrawonmint) + +```solidity +ISCDict memory ret = ISC.sandbox.call( + ISC.util.hn("accounts"), + ISC.util.hn("mintNFT"), + params, + allowance +); +``` + +6. The call return value will contain a `mintID` which we can use in, for example, another contract function to get the actual L1 NFT ID once it is created using the [`accounts.NFTIDbyMintID`](../../../reference/core-contracts/accounts.md#nftidbymintidd-mintid) function + +```solidity +function getNFTIDFromMintID(bytes memory mintID) public view returns (bytes memory) { + ISCDict memory params = ISCDict(new ISCDictItem[](1)); + params.items[0] = ISCDictItem("D", mintID); + + ISCDict memory ret = ISC.sandbox.callView( + ISC.util.hn("accounts"), + ISC.util.hn("NFTIDbyMintID"), + params + ); + return ret.items[0].value; +} +``` + +### Full Example Code + +```solidity +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "@iota/iscmagic/ISC.sol"; + +contract NFTContract { + event MintedNFT(bytes mintID); + + function mintNFT(string memory _name, string memory _mimeType, string memory _uri, uint64 _storageDeposit) public payable { + require(msg.value == _storageDeposit*(10**12), "Please send exact funds to pay for storage deposit"); + ISCAssets memory allowance; + allowance.baseTokens = _storageDeposit; + + ISCAgentID memory agentID = ISC.sandbox.getSenderAccount(); + + IRC27NFTMetadata memory metadata = IRC27NFTMetadata({ + standard: "IRC27", + version: "v1.0", + mimeType: _mimeType, + uri: _uri, + name: _name + }); + + ISCDict memory params = ISCDict(new ISCDictItem[](2)); + params.items[0] = ISCDictItem("I", bytes(IRC27NFTMetadataToString(metadata))); + params.items[1] = ISCDictItem("a", agentID.data); + + ISCDict memory ret = ISC.sandbox.call( + ISC.util.hn("accounts"), + ISC.util.hn("mintNFT"), + params, + allowance + ); + emit MintedNFT(ret.items[0].value); + } + + function getNFTIDFromMintID(bytes memory mintID) public view returns (bytes memory) { + ISCDict memory params = ISCDict(new ISCDictItem[](1)); + params.items[0] = ISCDictItem("D", mintID); + + ISCDict memory ret = ISC.sandbox.callView( + ISC.util.hn("accounts"), + ISC.util.hn("NFTIDbyMintID"), + params + ); + return ret.items[0].value; + } + + function IRC27NFTMetadataToString(IRC27NFTMetadata memory metadata) + public + pure + returns (string memory) + { + return string.concat( + '{"standard": "', + metadata.standard, + '", "version": "', + metadata.version, + '", "type": "', + metadata.mimeType, + '", "uri": "', + metadata.uri, + '", "name": "', + metadata.name, + '"}'); + } +} +``` diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/use-as-erc721.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/use-as-erc721.md new file mode 100644 index 00000000000..2263adca84c --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/use-as-erc721.md @@ -0,0 +1,33 @@ +--- +description: How to use a native NFT like an ERC721 NFT +image: /img/logo/WASP_logo_dark.png +tags: + - NFT + - EVM + - how-to +--- + +# Use as ERC721 +## About the `ERC721NFTs` contract + +The `ERC721NFTs` contract is a hardcoded contract at address `0x1074030000000000000000000000000000000000`. Every L1 NFT owned by the chain can be accessed through it. In this example, we will show you how to use it by using `transferFrom`. + +## Example Code + +1. ERC721 uses the `tokenID` for almost all interactions with it. So first, you should convert the `NFTID` to a `tokenID`: + +```solidity +uint256 tokenID = uint256(NFTID.unwrap(nftID)); +``` + +:::info Token ID to NFT ID + +You can use the ISCTypes.asNFTID() function to convert a Token ID to an NFT ID, by either using it on a token ID `tokenID.asNFTID();` or passing it to function `ISCTypes.asNFTID(tokenID)`. + +::: + +2. Transfer the token with ID `tokenID`, by using the `ERC20NFTs` contract, which is exposed in the library as `ISC.nfts`, and calling the standard `transferFrom` function: + +```solidity +ISC.nfts.transferFrom(msg.sender, _destination, tokenID); +``` diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/create-foundry.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/create-foundry.md new file mode 100644 index 00000000000..17ba120d40c --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/create-foundry.md @@ -0,0 +1,71 @@ +--- +description: How to create a L1 foundry +image: /img/logo/WASP_logo_dark.png +tags: + - foundry + - EVM + - how-to +--- +import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.md'; +import ObsoleteTokenCreation from '../../../_partials/how-tos/token/_obsolete_token_creation.md'; + +# Create a Foundry + + + +## About Foundries + +The Stardust update allows you to create your own native tokens. Native tokens are minted by a [Foundry](/tips/tips/TIP-0018/#foundry-output). +The Foundry allows you to specify your native token's maximum supply **once** and change the circulating supply. +This guide will show you how to create an L1 foundry using a L2 smart contract. + +## Example Code + + + +### 2. Define the Token Scheme + +Define the `NativeTokenScheme` by specifying its `mintedTokens`, `meltedTokens` and `maximumSupply`: + +```solidity +NativeTokenScheme memory nativeTokenScheme = NativeTokenScheme({ + mintedTokens: _mintedTokens, + meltedTokens: _meltedTokens, + maximumSupply: _maximumSupply +}); +``` + +### 3. Create the Foundry + +Create the foundry by calling the `ISC.accounts.foundryCreateNew(nativeTokenScheme, allowance)` function: + +```solidity +uint32 foundrySN = ISC.accounts.foundryCreateNew(nativeTokenScheme, allowance); +``` + +### Full Example Code + +```solidity +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import "@iota/iscmagic/ISC.sol"; + +contract CreateFoundry { + event CreatedFoundry(uint32 foundrySN); + + function createFoundry(uint _mintedTokens, uint _meltedTokens, uint _maximumSupply, uint64 _storageDeposit) public payable { + require(msg.value == _storageDeposit*(10**12), "Please send exact funds to pay for storage deposit"); + ISCAssets memory allowance; + allowance.baseTokens = _storageDeposit; + NativeTokenScheme memory nativeTokenScheme = NativeTokenScheme({ + mintedTokens: _mintedTokens, + meltedTokens: _meltedTokens, + maximumSupply: _maximumSupply + }); + uint32 foundrySN = ISC.accounts.foundryCreateNew(nativeTokenScheme, allowance); + emit CreatedFoundry(foundrySN); + } +} +``` diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/create-native-token.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/create-native-token.md new file mode 100644 index 00000000000..06baa4615d1 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/create-native-token.md @@ -0,0 +1,91 @@ +--- +description: How to Create a Native Token Foundary. +image: /img/logo/WASP_logo_dark.png +tags: + - foundry + - EVM + - how-to + - native tokens + - mint + - register +--- + +import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.md'; + +# Create a Native Token + +This guide will show you how you can efficiently mint new tokens and register them for use as ERC20 tokens with the [`createNativeTokenFoundry`](../../../reference/magic-contract/ISCAccounts.md#createnativetokenfoundry) function in one seamless operation. It will create a foundry on L1 and register it as an ERC20 on L2. This method ensures that only the foundry owner can mint tokens, maintaining security and control over the token creation process. + +## About Foundries + +The Stardust update allows you to create your own native tokens. Native tokens are minted by a [Foundry](/tips/tips/TIP-0018/#foundry-output). +The Foundry lets you specify your native token's maximum supply **once** and change the circulating supply. + +## Example Code + + + +### 2. Define the Token Scheme + +Define the [`NativeTokenScheme`](../../../reference/magic-contract/ISCTypes.md#nativetokenscheme) by specifying the `maximumSupply`. + +```solidity +NativeTokenScheme memory nativeTokenScheme = NativeTokenScheme({ + mintedTokens: 0, + meltedTokens: 0, + maximumSupply: _maximumSupply +}); +``` + +### 3. Mint and Register Native Token + +Minting native tokens and registering them as ERC20 tokens using [`createNativeTokenFoundry`](../../../reference/magic-contract/ISCAccounts.md#createnativetokenfoundry) method + +```solidity +uint32 foundrySN = ISC.accounts.createNativeTokenFoundry( + _tokenName, + _tokenSymbol, + _tokenDecimals, + nativeTokenScheme, + allowance +); +``` + +## Full Example Code + +```solidity +pragma solidity ^0.8.0; + +import "@iota/iscmagic/ISC.sol"; + +contract MyToken { + event MintedToken(uint32 foundrySN); + + constructor( + string memory _tokenName, + string memory _tokenSymbol, + uint8 _tokenDecimals, + uint256 _maximumSupply, + uint64 _storageDeposit + ) payable { + require(msg.value == _storageDeposit * (10**12), "Please send exact funds to pay for storage deposit"); + ISCAssets memory allowance; + allowance.baseTokens = _storageDeposit; + + NativeTokenScheme memory nativeTokenScheme = NativeTokenScheme({ + mintedTokens: 0, + meltedTokens: 0, + maximumSupply: _maximumSupply + }); + + uint32 foundrySN = ISC.accounts.createNativeTokenFoundry( + _tokenName, + _tokenSymbol, + _tokenDecimals, + nativeTokenScheme, + allowance + ); + emit MintedToken(foundrySN); + } +} +``` diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/erc20-native-token.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/erc20-native-token.md new file mode 100644 index 00000000000..eef11254681 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/erc20-native-token.md @@ -0,0 +1,45 @@ +--- +description: How to use the custom functionality of ERC20NativeToken +image: /img/logo/WASP_logo_dark.png +tags: + - native token + - erc20 + - EVM + - how-to +--- + +# Custom ERC20 Functions + +Once you [registered your native token as ERC20](./erc20-native-token.md) you can use it like any other ERC20 token, with functions like +`transfer`, `balanceOf`, etc. But, as the ERC20 token maps the native token on L2, there are some additional ISC features +you can take advantage of. + +## Example Code + +### Get Your `nativeTokenID` + +You can use the `erc20NativeTokensAddress` function and the Foundry serial number to get the contract address: + +```solidity +ERC20NativeTokens token = ERC20NativeTokens( + ISC.sandbox.erc20NativeTokensAddress(_foundrySN) +); +``` + +* `nativeTokenID` will give you the native token ID of the ERC20 token: + +```solidity +NativeTokenID memory id =token.nativeTokenID(); +``` + +### Full Example Code + +```solidity +function nativeTokenID(uint32 _foundrySN) public view returns (bytes memory) { + ERC20NativeTokens token = ERC20NativeTokens( + ISC.sandbox.erc20NativeTokensAddress(_foundrySN) + ); + NativeTokenID memory id =token.nativeTokenID(); + return id.data; +} +``` diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/introduction.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/introduction.md new file mode 100644 index 00000000000..83fb4021e47 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/introduction.md @@ -0,0 +1,18 @@ +--- +description: How to handle native tokens on L2 and use them as ERC20 +image: /img/logo/WASP_logo_dark.png +tags: + - native token + - EVM + - how-to +--- +import DocCardList from '@theme/DocCardList'; + +# Native Token and ERC20NativeToken + +The IOTA L1 has functionality to create L1 tokens, also called native tokens. To use these native tokens on L2, you have +a ERC20 contract called `ERC20NativeToken`. The following guides will show you how to [create a foundry](create-foundry.md) +that can [mint your own L1 token from L2](mint-token.md), and [register](register-token.md) it as `ERC20NativeToken`, +so it can be used like any other ERC20 token with some additional features. + + \ No newline at end of file diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/mint-token.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/mint-token.md new file mode 100644 index 00000000000..bd79533d844 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/mint-token.md @@ -0,0 +1,41 @@ +--- +description: How to mint native token on an L1 foundry. +image: /img/logo/WASP_logo_dark.png +tags: + - foundry + - EVM + - how-to + - native tokens + - mint +--- +import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.md'; + +# Mint Native Tokens + +To mint tokens from a [foundry](/tips/tips/TIP-0018/#foundry-output), you first need to be aware that only the foundry owner can mint token, so you should execute the `ISC.accounts.mintNativeTokens` function in the same contract where you also [created the native token](./create-native-token.md). + +## Example Code + + + +### 2. Mint the Native Token + +Mint the native token specifying the foundry serial number, the amount to mint and the allowance. + +```solidity +ISC.accounts.mintNativeTokens(_foundrySN, _amount, allowance); +``` + +## Full Example Code + +```solidity +event MintedNativeTokens(uint32 foundrySN, uint amount); + +function mintNativeTokens(uint32 _foundrySN, uint _amount, uint64 _storageDeposit) public payable { + require(msg.value == _storageDeposit*(10**12), "Please send exact funds to pay for storage deposit"); + ISCAssets memory allowance; + allowance.baseTokens = _storageDeposit; + ISC.accounts.mintNativeTokens(_foundrySN, _amount, allowance); + emit MintedNativeTokens(_foundrySN, _amount); +} +``` diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/register-token.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/register-token.md new file mode 100644 index 00000000000..990ae5e69b3 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/register-token.md @@ -0,0 +1,56 @@ +--- +description: How to register a native token as ERC20 +image: /img/logo/WASP_logo_dark.png +tags: + - ERC20 + - EVM + - how-to +--- +import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.md'; +import ObsoleteTokenCreation from '../../../_partials/how-tos/token/_obsolete_token_creation.md'; + +# Register Tokens + + + +To properly use your native tokens, you should register them as ERC20 using the `registerERC20NativeToken` function from the ISC magic contract. + +## Example Code + + + + +### 2. Register the Native Tokens + +Register the native tokens specifying: +* the foundry serial number +* a name +* a symbol +* it's decimals +* the allowance. +```solidity +ISC.sandbox.registerERC20NativeToken(_foundrySN, _name, _symbol, _decimals, allowance); +``` + +### 3. Get the Contract's Address + +Get the ERC20 contract address with `erc20NativeTokensAddress`: + +```solidity +address erc20address = ISC.sandbox.erc20NativeTokensAddress(_foundrySN); +``` + +### Full Example Code + +```solidity +event ERC20Address(address erc20address); + +function registerERC20NativeToken(uint32 _foundrySN, string calldata _name, string calldata _symbol, uint8 _decimals, uint64 _storageDeposit) public payable { +require(msg.value == _storageDeposit*(10**12), "Please send exact funds to pay for storage deposit"); +ISCAssets memory allowance; +allowance.baseTokens = _storageDeposit; +ISC.sandbox.registerERC20NativeToken(_foundrySN, _name, _symbol, _decimals, allowance); +address erc20address = ISC.sandbox.erc20NativeTokensAddress(_foundrySN); +emit ERC20Address(erc20address); +} +``` diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/create-a-basic-contract.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/create-a-basic-contract.md new file mode 100644 index 00000000000..d060b3732ff --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/create-a-basic-contract.md @@ -0,0 +1,53 @@ +--- +description: Basic smart contract example. +image: /img/logo/WASP_logo_dark.png +tags: + - smart contracts + - how to + - basic contract +--- +import DeployAdmonition from '../_admonitions/_deploy_a_smart_contract.md'; + +# Basic Smart Contract Example + +[Solidity](https://docs.soliditylang.org/en/v0.8.16/) smart contracts on IOTA Smart Contracts are compatible with +Solidity smart contracts on any other network. Most smart contracts will work directly without any modification. To get +a rough indication of what a simple Solidity smart contract looks like, see the example below: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.6; + +contract Counter { + uint private count; + + constructor() { + count = 0; + } + + function increment() public { + count += 1; + } + + function decrement() public { + require(count > 0, "Count is already zero"); + count -= 1; + } + + function getCount() public view returns (uint) { + return count; + } +} + +``` + +This contract simply updates a `count` variable. It has +three [entry points](../explanations/smart-contract-anatomy.md#entry-points): + +* `increment` and `decrement`: Two full entry points that can alter + the [state](../explanations/smart-contract-anatomy.md#state), i.e. the `count variable`. +* `getCount`: A view only entry point, which simply renders the current `count` state. + +For more information, please visit the [official Solidity documentation](https://docs.soliditylang.org/). + + \ No newline at end of file diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/deploy-a-smart-contract.mdx b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/deploy-a-smart-contract.mdx new file mode 100644 index 00000000000..0a1860715ec --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/deploy-a-smart-contract.mdx @@ -0,0 +1,196 @@ +--- +tags: +- Smart Contract Deployment +- Shimmer EVM +- IOTA EVM +- Remix IDE +- Hardhat +- EVM Testnet +image: /img/logo/WASP_logo_dark.png +description: 'Learn how to deploy smart contracts to IOTA EVM, Shimmer EVM and EVM Testnet using popular tools like Remix and Hardhat.' +--- +import {AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; +import HardhatConfig from '../_partials/_hardhat_config.md'; +import MetamaskButtons from '../../../../_partials/_metamask_buttons.mdx'; +import { Networks } from '@theme/constant'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Deploy a Smart Contract + +You can deploy your smart contracts to any of your [EVM chains](/build/networks-endpoints/) using popular tools like [Remix](#remix) +and [Hardhat](#hardhat). + +:::tip Get a Basic Contract + +This guide will deploy the `Counter` contract you can find in +the [How to Create a Basic Solidity Contract Guide](create-a-basic-contract.md). + +::: + + + + +Deploying a Solidity smart contract using Remix is a straightforward process that doesn't require any installation or +setup of development environments on your machine. Remix is a powerful, browser-based IDE that allows you to write, +compile, and deploy smart contracts. + +### 1. Connect to Metamask + +Before you get started, make sure you have connected Metamask to your network of choice. + +:::tip Networks & Endpoints + +You can check the connection details in the [Networks & Endpoints section](/build/networks-endpoints/). + +::: + + + +### 2. Access Remix IDE + +Open your web browser and navigate to [Remix IDE](https://remix.ethereum.org/). + +### 3. Create Your Smart Contract + +1. In the `File Explorer` tab on the left, click the `Create New File` icon. +2. Name your file `Counter.sol`. +3. Copy the Solidity code for the [basic counter smart contract](create-a-basic-contract.md) and paste it into + the `Counter.sol` file you just created in Remix. + +### 4. Compile Your Smart Contract + +1. Navigate to the `Solidity Compiler` tab on the left sidebar. +2. Select the appropriate compiler version that matches the version specified in your contract (`^0.8.6` or similar). + You might need to enable "Auto compile" or click the "Compile" button manually. +3. If there are errors, Remix will display them, and you'll need to correct them before proceeding. + +### 5. Deploy Your Smart Contract + +1. Switch to the "Deploy & Run Transactions" tab on the left sidebar. +2. In the "Environment" dropdown, select and select `Injected Web3` from the `Environment` dropdown. + + ![Select Injected Provider from the Environment dropdown](/img/evm/remix-injected-provider-metamask.png) + +3. After selecting the environment, make sure the contract Counter is selected in the `Contract` dropdown. +4. Click the `Deploy` button. If you're using an Ethereum network, confirm the transaction in your Web3 wallet. + +### 6. Interact with Your Deployed Contract + +Once deployed, the contract instance will appear under the `Deployed Contracts` section. +Here, you can interact with your contract by calling its functions. For the Counter contract, you'll see buttons to call +its `increment`, `decrement`, and `getCount` functions directly from Remix. + + + + +The first thing you'll need to deploy a smart contract using [Hardhat](https://hardhat.org/) is to set up a Hardhat +project. Here's a step-by-step guide: + +### Requirements + +* [Node.js](https://nodejs.org/). +* [npm](https://www.npmjs.com/) or [yarn](https://yarnpkg.com/). + +### 1. Set Up Hardhat + +1. Open a new terminal window. +2. Create a new directory for your project, and navigate into it. For example: + ```bash + mkdir deploy-a-basic-contract && + cd deploy-a-basic-contract + ``` +3. Create a new node project by running: + ```bash + npm init -y + ``` +4. Install Hardhat by running: + ```bash + npm install --save-dev hardhat + ``` +5. Create a Hardhat Project by running the following command: + ```bash + npx hardhat init + ``` + + Select `Create a JavaScript project` (or whatever applies to your project) when prompted and answer the setup questions (you can press enter to + accept defaults). + +### 2. Add Your Contract + +1. Inside the `contracts` folder, create a new file called `Counter.sol` and paste the content of + the [Counter Basic Contract](create-a-basic-contract.md). + +### 3. Create a Deployment Script + +1. Navigate to the `scripts` folder. +2. Create a new file called `deploy.js` with the following code: + + ```javascript + async function main() { + const Counter = await ethers.getContractFactory("Counter"); + const counter = await Counter.deploy(); + + console.log("Counter deployed to:", await counter.getAddress()); + } + + main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); + ``` + +### 4. Compile and Deploy Your Contract + +1. Add your preferred network parameters to the `hardhat.config.js`, for example: + + + +:::info Export the Metamask Private Key + +1. Click on the Metamask logo in the upper right corner. +2. Select the account you want to export. +3. On the account page, click the menu (three dots) in the upper right corner, then click the "Account Details" button. +4. Click on "Export Private Key". +5. Enter your wallet password to access your private key and click `Confirm` to continue. +6. Your private key will now be displayed. Click to copy it and save it in a safe place. + +You can find more information in the [official Metamask Documentation](https://support.metamask.io/managing-my-wallet/secret-recovery-phrase-and-private-keys/how-to-export-an-accounts-private-key/). + +::: + +:::caution + +Currently, there is no validation service available for EVM/Solidity smart contracts on IOTA Smart Contracts, which is +often offered through block explorer APIs. + +::: + +2. Compile your contract by running the following command: + + ```bash + npx hardhat compile + ``` + +3. If you have no compilation errors, you can deploy your contract by running the following command: + + ```bash + npx hardhat run scripts/deploy.js --network evm-testnet + ``` + + **Expected output**: + + ```bash + Counter deployed to: 0x123456789ABCDEFGHIJK123456789ABCDEFGHIJK + ``` + ***** `0x123456789ABCDEFGHIJK123456789ABCDEFGHIJK` is the contract unlock address. + +4. You can verify your contract by visiting + the [EVM Testnet Explorer](https://explorer.evm.testnet.shimmer.network/), + and searching for the address from the previous step. If you access the `Contract` tab, you should be able to see + your code and interact with your contract. + + + \ No newline at end of file diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/introduction.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/introduction.md new file mode 100644 index 00000000000..cb6c63bbc87 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/introduction.md @@ -0,0 +1,29 @@ +--- +description: 'Explore the how-to guides for IOTA Smart Contracts, offering step-by-step instructions on various topics and functionalities.' +image: /img/logo/WASP_logo_dark.png +tags: + + - EVM + - Solidity + - smart contracts + - Ethereum + - explanation + - how-to guides + - instructions + - code examples +--- + +# About How-to Guides + +This section has several how-to guides that provide step-by-step instructions on various topics and functionalities. You +can use these guides to understand and implement specific tasks or features within your application. Whether you are a +beginner or an experienced developer, the how-to guides offer clear and concise explanations, making integrating IOTA smart contracts +functionality into your projects easier. + +To make the most of the how-to guides in this section, identify the specific topic or functionality you want to explore. +Whether you want to [get funds on L2](send-funds-from-L1-to-L2.mdx), [add ISC specific functionality](introduction.md), +or [send funds to L1](./core-contracts/basics/send-assets-to-l1.mdx), you can find dedicated guides that walk you through the process. + +With the how-to guides in the IOTA SDK, you can overcome implementation hurdles and gain a deeper understanding +of the IOTA ecosystem. These guides empower you with the knowledge and practical examples to seamlessly integrate IOTA +functionality into your projects. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/send-ERC20-across-chains.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/send-ERC20-across-chains.md new file mode 100644 index 00000000000..af8cc67fa54 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/send-ERC20-across-chains.md @@ -0,0 +1,297 @@ +# Send ERC20 Tokens Across Chains + +## Introduction + +[LayerZero OFT V2](https://docs.layerzero.network/v2) enables cross-chain transfers of existing ERC20 tokens, such as wSMR and wIOTA (wrapped versions of the native gas tokens SMR and IOTA on ShimmerEVM and IOTA EVM respectively). For testing purposes, Sepolia is chosen as the source chain, while the BNB Testnet is chosen as the destination chain. + +:::info Community Libs + +You can clone the Utilities for LayerZero OFT V2 from [IOTA Community GitHub Repository](https://github.com/iota-community/layerzero-oft-v2-utils). + +::: + +### Why Would a User Need to Send ERC20 Tokens Across Chains? + +Sending ERC20 tokens across chains allows users to leverage different blockchain networks' strengths and unique features, optimize costs, and manage risks more effectively. This flexibility is crucial as the blockchain ecosystem continues to grow and diversify. + +#### Send Existing ERC20 Tokens Across Chains + +You need both the [OFT Adapter](https://docs.layerzero.network/v2/developers/evm/oft/adapter) and OFT contracts to enable existing ERC20 tokens for cross-chain sending, + +#### Create New Cross-chain Fungible Tokens + +If you are about to launch a new ERC20 token, you can use the [OFT standard](https://docs.layerzero.network/v2/developers/evm/oft/quickstart) to enable cross-chain sending without the OFT Adapter. + +## How To Use IOTA's Utilities for LayerZero OFT V2 + +The [Utilities for LayerZero OFT V2](https://github.com/iota-community/layerzero-oft-v2-utils) facilitate cross-chain sending of ERC20 tokens between a source chain (e.g., Sepolia or ShimmerEVM Testnet) and a destination chain (e.g., BNB Testnet or IOTA EVM Testnet). + +:::tip Further Information + +You can learn more about the available options in the [Layer Zero Documentation](https://docs.layerzero.network/v2/developers/evm/gas-settings/options#option-types.). + +::: + +### Send Tokens From One Source Chain to Another Destination Chain (and Vice Versa) + +To send existing ERC20 tokens, you will need both the OFT Adapter contract on the source chain and the OFT contract on the destination chain. You should then use the following procedure: + +#### 1. Approve the tokens + +The sender must approve their ERC20 tokens for the OFT Adapter contract. + +```typescript +const approveTx = await erc20TokenContract.approve(oftAdapterContractAddress, amountInWei); +``` + +#### 2. Estimate the fee + +The sender calls the function `quoteSend()` of the OFT Adapter contract to estimate the cross-chain fee to be paid in native tokens on the source chain. + +```typescript + const sendParam = [ + lzEndpointIdOnDestChain, + receiverAddressInBytes32, + amountInWei, + amountInWei, + options, // additional options + "0x", // composed message for the send() operation + "0x", // OFT command to be executed, unused in default OFT implementations + ]; + + // https://github.com/LayerZero-Labs/LayerZero-v2/blob/main/oapp/contracts/oft/interfaces/IOFT.sol#L127C60-L127C73 + // false is set for _payInLzToken Flag indicating whether the caller is paying in the LZ token + const [nativeFee] = await myOFTAdapterContract.quoteSend(sendParam as any, false); +``` + +#### 3. Send the tokens + +The sender calls the function `send()` of the OFT Adapter contract to transfer tokens from the source chain to the destination chain. + +```typescript + const sendTx = await myOFTAdapterContract.send( + sendParam as any, + [nativeFee, 0] as any, // set 0 for lzTokenFee + sender.address, // refund address + { + value: nativeFee, + }, + ); + const sendTxReceipt = await sendTx.wait(); + console.log("sendOFT - send tx on source chain:", sendTxReceipt?.hash); +``` + +#### 4. (Optional) Wait for Finalization + +The sender can wait for transaction finalization on the destination chain using the library [@layerzerolabs/scan-client](https://www.npmjs.com/package/@layerzerolabs/scan-client#example-usage). +```typescript + const deliveredMsg = await waitForMessageReceived( + Number(lzEndpointIdOnDestChain), + sendTxReceipt?.hash as string, + ); + console.log("sendOFT - received tx on destination chain:", deliveredMsg?.dstTxHash); +``` + +### Send the OFT-wrapped Tokens Back + +To send back the OFT-wrapped tokens on the destination chain to the source chain, the procedure is similar, except that the approval step is not needed: + +#### 1. Estimate the fee + +The sender calls the function `quoteSend()` of the OFT contract to estimate the cross-chain fee to be paid in native tokens on the sender chain. + +```typescript + // Set the send param + // https://github.com/LayerZero-Labs/LayerZero-v2/blob/main/oapp/contracts/oft/interfaces/IOFT.sol#L10 + const sendParam = [ + lzEndpointIdOnSrcChain, // Sepolia + receiverAddressInBytes32, + amountInWei, + amountInWei, + options, // additional options + "0x", // composed message for the send() operation + "0x", // OFT command to be executed, unused in default OFT implementations + ]; + + // Step 1: call the func quoteSend() to estimate cross-chain fee to be paid in native on the source chain + // https://github.com/LayerZero-Labs/LayerZero-v2/blob/main/oapp/contracts/oft/interfaces/IOFT.sol#L127C60-L127C73 + // false is set for _payInLzToken Flag indicating whether the caller is paying in the LZ token + const [nativeFee] = await myOFTContract.quoteSend(sendParam as any, false); + console.log("sendOFTBack - estimated nativeFee:", ethers.formatEther(nativeFee)); + ``` + +#### 2. Send the tokens + +The sender calls the function `send()` of the OFT contract to transfer tokens from the destination chain back to the source chain. + +```typescript +const sendTx = await myOFTContract.send( + sendParam as any, + [nativeFee, 0] as any, // set 0 for lzTokenFee + sender.address, // refund address + { + value: nativeFee, + }, + ); + const sendTxReceipt = await sendTx.wait(); + console.log("sendOFTBack - send tx on source chain:", sendTxReceipt?.hash); + ``` + +#### 3. (Optional) Wait for Finalization + +The sender can wait for transaction finalization on the destination chain using the library `@layerzerolabs/scan-client`. +```typescript + const deliveredMsg = await waitForMessageReceived( + Number(lzEndpointIdOnDestChain), + sendTxReceipt?.hash as string, + ); + console.log("sendOFTBack - received tx on destination chain:", deliveredMsg?.dstTxHash); + ``` + +## Sample Solidity Code for OFT Adapter and OFT Contracts in the `contracts-standard` Folder + +The [contracts-standard](https://github.com/iota-community/layerzero-oft-v2-utils/tree/main/contracts-standard) contains scripts to: + +- [Deploy the OFT Adapter and OFT contracts](#deploy-the-oft-adapter-contract-on-the-source-chain). +- [Set your trusted peers](#optional-set-the-trusted-peers). +- Set enforced options. +- [Send tokens from the source chain to the destination chain](#send-the-origin-tokens-from-the-source-chain-to-the-destination-chain), +and [vice versa](#send-oft-wrapped-tokens-back-from-the-destination-chain-to-the-origin-chain). + +### Install the Library + +After you have cloned the [IOTA Community Utilities for LayerZero OFT V2 repository](https://github.com/iota-community/layerzero-oft-v2-utils/tree/main), you should run the following command to install: + +``` +yarn +``` + +### Compile the Contracts + +If you want to use the standard implementation for ERC20, copy the [`contracts-standard`](https://github.com/iota-community/layerzero-oft-v2-utils/tree/main/contracts-standard) folder to `contracts`. If you want to use a custom implementation, copy the [`contracts-wiota`](https://github.com/iota-community/layerzero-oft-v2-utils/tree/main/contracts-wiota) to `contracts`. Then, run the following command to compile the contracts: + +```bash +yarn compile +``` + +### Set Your Configuration + +You should copy the template [`.env.example`](https://github.com/iota-community/layerzero-oft-v2-utils/blob/main/.env.example) file to a file called `.env`, and edit any of the configuration options you see fit. + +```bash +cp .env.example .env +``` + +### Deploy the Contracts + +#### Deploy the OFT Adapter Contract On the Source Chain + +The OFT Adapter facilitates the expansion of an existing token to any supported blockchain as a native token, maintaining a unified global supply and inheriting all features of the OFT Standard. This intermediary contract manages the sending and receiving of pre-deployed tokens. + +For instance, when an ERC20 token is transferred from the source chain (Chain A), it gets locked in the OFT Adapter. Consequently, a corresponding token is minted on the destination chain (Chain B) through the paired OFT Contract. + +```bash +yarn deploy-oft-adapter-sepolia +``` + +Expected log output : + +```bash +npx hardhat run scripts/deploy_oft_adapter.ts --network sepolia +Deployed MyOFTAdapter contract address: 0x4daa81978576cB91a2e1919960e90e46c2a6D586 +Done in 6.67s. +``` + +#### Deploy OFT on the Destination Chain + +You can use the following command to deploy OFT on destination chain (e.g. BNB Testnet): + +```bash +yarn deploy-oft-bnb-testnet +``` + +Expected log output : + +```bash +npx hardhat run scripts/deploy_oft.ts --network bnbTestnet +Deployed MyOFT contract address: 0xCc337C2e69F4Eb8EaBcf632a1fC5B8F729dC47F1 +Done in 6.68s. +``` + +### (optional) Set the Trusted Peers + +#### On OFTAdapter + +You can set the trusted peer in the source chain's OFT Adapter (e.g., Sepolia) using the following command: + +```bash +yarn set-peer-oft-adapter-sepolia +``` + +Expected log output : + +```bash +npx hardhat run scripts/set_peer_oft_adapter.ts --network sepolia +setPeerMyOFTAdapter - oftAdapterContractAddress:0x4daa81978576cB91a2e1919960e90e46c2a6D586, lzEndpointIdOnDestChain:40102, oftContractAddress:0xCc337C2e69F4Eb8EaBcf632a1fC5B8F729dC47F1 +MyOFTAdapter - setPeer tx: 0xc17e7a54d96325768b6427ce893d9b6b7ed04bd920089b63a3f96c005073e9c2 +Done in 14.10s. +``` + +#### On OFT + +You can add a trusted peer in the destination chain (e.g. BNB Testnet) using the following command: + +```bash +yarn set-peer-oft-bnb-testnet +``` + +Expected log output : + +```bash +npx hardhat run scripts/set_peer_oft.ts --network bnbTestnet +setPeerMyOFT - oftContractAddress:0xCc337C2e69F4Eb8EaBcf632a1fC5B8F729dC47F1, lzEndpointIdOnSrcChain:40161, oftAdapterContractAddress:0x4daa81978576cB91a2e1919960e90e46c2a6D586 +MyOFT - setPeer tx: 0xb0012378ee14c9df5c9f86980dd9c96fc8aedb3c19d92c1d91a4259f3981ac35 +Done in 4.66s. +``` + +### Send the Origin Tokens from the Source Chain to the Destination Chain + + +You can use the following command to send tokens from the source chain to the destination chain: + +```bash +yarn send-oft-from-sepolia +``` + +Expected log output : + +```bash +npx hardhat run scripts/send_oft.ts --network sepolia +sendOFT - oftAdapterContractAddress:0x5D7Cbc05fc6df2832c40023f1Eb2755628C51D81, oftContractAddress:0x075e512E25b45a3EaF8b432220F0Ca8D4e3c6a58, lzEndpointIdOnSrcChain:40161, lzEndpointIdOnDestChain:40102, gasDropInWeiOnDestChain:1000000000000000, executorLzReceiveOptionMaxGas:200000, receivingAccountAddress:0x5e812d3128D8fD7CEac08CEca1Cd879E76a6E028, sender: 0x57a4bd139fb673d364a6f12df9177a3f686625f3, amount:2 +sendOFT - approve tx: 0x8fa692edb47b1ad9d21f60b0fa30993e5cd3abd78c3c56fb4f38db5f9b8ac369 +sendOFT - estimated nativeFee: 0.000734209489447653 +sendOFT - send tx on source chain: 0xeb3e44310a09ae2ab2f0d6d6d3fdfd7c490f8ac536bb20a5e16999b23232ef67 +Wait for cross-chain tx finalization by LayerZero ... +sendOFT - received tx on destination chain: 0xc2e5a4be8ae67718e817ff585a32765e393835880068f408fd7724667a25a46c +``` + +### Send Oft-Wrapped Tokens Back From the Destination Chain to the Origin Chain + +You can use the following command to send the OFT-wrapped tokens back to the origin chain: + + +```bash +yarn send-oft-back-from-bnb-testnet +``` + +Expected log output : + +```bash +npx hardhat run scripts/send_oft_back.ts --network bnbTestnet +sendOFTBack - oftAdapterContractAddress:0x5D7Cbc05fc6df2832c40023f1Eb2755628C51D81, oftContractAddress:0x075e512E25b45a3EaF8b432220F0Ca8D4e3c6a58, lzEndpointIdOnSrcChain:40161, lzEndpointIdOnDestChain:40102, gasDropInWeiOnDestChain:1000000000000000, executorLzReceiveOptionMaxGas:200000, receivingAccountAddress:0x57A4bD139Fb673D364A6f12Df9177A3f686625F3, sender: 0x5e812d3128D8fD7CEac08CEca1Cd879E76a6E028, amount:2 +sendOFTBack - estimated nativeFee: 0.054815809525020364 +sendOFTBack - send tx on source chain: 0x41bcf78b310dc1bbf9b4005f7412d995011c7815ad5af9cc26b37370e75bbfeb +Wait for cross-chain tx finalization by LayerZero ... +sendOFTBack - received tx on destination chain: 0xc1031694e92512a0189885ad6419e33196a65b8ae56baa9d555be8686d6d42fe +``` + diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/send-NFTs-across-chains.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/send-NFTs-across-chains.md new file mode 100644 index 00000000000..273c11009b4 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/send-NFTs-across-chains.md @@ -0,0 +1,365 @@ +# Send NFTs Across Chains + +## Introduction + +[LayerZero ONFT V1FV](https://docs.layerzero.network/V1) enables cross-chain transfers of existing ERC721 tokens. For +testing purposes, the ShimmerEVM Testnet is chosen as the source chain, while the BNB Testnet is chosen as the destination +chain. + +:::info Community Libs + +You can clone the Utilities for LayerZero ONFT V1 +from [IOTA Community GitHub Repository](https://github.com/iota-community/layerzero-onft-v1-utils). + +::: + +## Why Would a User Need to Send ERC721 Tokens Across Chains? + +By facilitating the movement of ERC721 tokens across chains, users gain flexibility and can optimize their NFT usage +according to their specific needs, preferences, and circumstances. + +### Enable the Existing ERC721 Tokens for Cross-Chain Sending + +To enable the existing ERC721 tokens for cross-chain sending, you will need the `ProxyONFT` contract on the source +chain, +and the ONFT contract on the destination chain) are needed. + +The origin NFT token will be locked in the `ProxyONFT` contract so that the ONFT-wrapped tokens will be minted on the +destination chain. If the NFT token already exists on the destination chain (i.e., when the ONFT-wrapped token on +the destination chain is sent back to the source chain), no new token minting will happen. Instead, the NFT tokens will be +transferred from the ONFT contract to the user's wallet address. Relevant code + +### Enable Cross-Chain Sending for Unloached ERC721 NFTs + +If you are launching a new ERC721 token, you can use the ONFT standard to enable cross-chain sending without the need of +`ProxyONFT`. As with existing tokens, the NFT will be locked on the source chain and minted or transferred on the destination chain. + +:::info Contract Documentation + +- [ProxyONFT721](https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/721#proxyonft721sol) +- [ProxyONFT1155](https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/1155#proxyonft1155sol) +- [ONFT721](https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/721#onft721sol) +- [ONFT1155](https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/1155#onft1155sol) + +::: + +## Scripts + +### Deploy the ProxyONFT and ONFT Contracts + +#### For ERC721 + +- MyProxyONFT721.sol: + - CTOR: + - [`minGasToTransferAndStore`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/onft721/ONFT721Core.sol#L169): + The minimum gas needed to transfer and store your NFT is typically 100k for ERC721. This value would vary + depending on your contract complexity; it's recommended to test. If this value is set too low, the destination + tx will fail, and a manual retry is needed. + - `lzEndpoint`: LayerZero Endpoint on the source chain. + - `proxyToken`: deployed contract address of the NFT tokens on the source chain. + +- MyONFT721.sol: + - CTOR: + - `name`: name of the ONFT-wrapped tokens on the destination chain + - `symbol`: symbol of the ONFT-wrapped tokens on the destination chain + - [`minGasToTransferAndStore`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/onft721/ONFT721Core.sol#L169): + The minimum gas needed to transfer and store your NFT typically 100k for ERC721. This value would vary + depending on your contract complexity; it's recommended to test. If this value is set too low, the destination + tx will fail, and a manual retry is needed. + - `lzEndpoint`: - lzEndpoint: LayerZero Endpoint on the destination chain + +### Set the Trusted Remote + +For **existing ERC721 tokens**, the `ProxyONFT` and `ONFT` contract instances must be paired. + +For the **upcoming ERC721 tokens** that want to leverage the `ONFT` standard, the `ONFT` contract instance on the source chain +needs to be paired with another `ONFT` contract instance on the destination chain. + +You can set this using the [`setTrustedRemote`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/LzApp.sol#L138) method. + +### Set the `minGasLimit` + +Both the `ProxyONFT` and the `ONFT` contract instanceS need to be set for minimum gas on destination([`minGasLimit`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/LzApp.sol#L85C37-L85C48)). + +You can set his using the [`setMinDstGas`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/LzApp.sol#L159) method. + +:::info + +It is required that `minDstGas` <= `providedGasLimit`, which is to be set via `adapterParams` upon cross-chain sending on +the source chain. + +::: + +### Set the Batch Size Limit + +Both the `ProxyONFT` and the `ONFT` contract instances need to set a limit for the batch size on the source +chain to limit the number of tokens to be sent to another chain when using the +[`sendBatchFrom`](https://github.com/LayerZero-Labs/solidity-examples/blob/c04e7d211b1b610f84761df943e6a38b0a53d304/contracts/token/onft721/ONFT721Core.sol#L67) +method. + +You can set this using the [`setDstChainIdToBatchLimit`](https://github.com/LayerZero-Labs/solidity-examples/blob/c04e7d211b1b610f84761df943e6a38b0a53d304/contracts/token/onft721/ONFT721Core.sol#L194) method; the default value is 1. + +## How To Send Tokens From a Source Chain to a Destination Chain (and Vice-Versa) + +### Required Contracts + +#### From the Source Chain to the Destination Chain + +For the existing ERC721 tokens, you will need the `ProxyONFT` contract on the source chain and the `ONFT` contract on +the destination chain. The procedure is as follows: + +1. The sender approves his ERC721 tokens for the `ProxyONFT` contract. +2. The sender calls the function [`estimateSendFee()`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/onft721/interfaces/IONFT721Core.sol#L70) of the ProxyONFT contract to estimate cross-chain fee to be paid in + native on the source chain. +3. The sender calls the function [`sendFrom()`](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/onft721/interfaces/IONFT721Core.sol#L36) of the ProxyONFT contract to transfer tokens on source chain to destination + chain. +4. (Optional) Wait for the transaction finalization on the destination chain by using the + [@layerzerolabs/scan-client](https://www.npmjs.com/package/@layerzerolabs/scan-client#example-usage) library. + +#### From the Destination Chain Back to the Source Chain + +To send back the ONFT-wrapped tokens on the destination chain to the source chain, the procedure is similar as the +approve step is also required, but the operations will happen on the `ONFT` contract. + +#### References and Tools + +##### `AdapterParams` + +- You can use the [LayerZero Repository](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/libs/LzLib.sol#L44) as a reference to set gas drop on the destination in `adapterParams`. + - The provided gas drop must be `<=` the config one. Otherwise, you will get [`dstNativeAmt` too large](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/mocks/LZEndpointMock.sol#L413) error. +- You can use the [LayerZero Repository](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/libs/LzLib.sol#L34) as a refernce to set default `adapterParams` without needing a gas drop. + +##### LayerZero + +- [LayerZero Endpoint V1](https://docs.layerzero.network/v1/developers/technical-reference/mainnet/mainnet-addresses) +- [LayerZero explorer](https://Testnet.layerzeroscan.com/) + +### Install the Library + +After you have cloned +the [IOTA Community Utilities for LayerZero ONFT V2 repository](https://github.com/iota-community/layerzero-onft-v1-utils), +you should run the following command to install: + +```bash +yarn +``` + +### Compile the Contracts + +If you want to use the standard implementation for ERC20, copy +the [`contracts-standard`](https://github.com/iota-community/layerzero-oft-V1-utils/tree/main/contracts-standard) folder +to `contracts`. If you want to use a custom implementation, copy +the [`contracts-wiota`](https://github.com/iota-community/layerzero-oft-V1-utils/tree/main/contracts-wiota) +to `contracts`. Then, run the following command to compile the contracts: + +```bash +yarn compile +``` + +### Set Your Configuration + +You should copy the +template [`.env.example`](https://github.com/iota-community/layerzero-oft-V1-utils/blob/main/.env.example) file to a +file called `.env`, and edit any of the configuration options you see fit. + +```bash +cp .env.example .env +``` + +### Deploy the Contracts + +#### Deploy a mock ERC721 + +```bash +yarn deploy-ERC721-mock-smr-Testnet +``` + +Expected log output : + +```bash +npx hardhat run scripts/deploy_ERC721.ts --network shimmerEvmTestnet +Deployed ERC721Mock contract address:0xFddbA8928a763679fb8C99d12541B7c6177e9c3c +Done in 4.49s. +``` + +#### Deploy `ProxyONFT721` on the source chain + +You can use the following command to deploy ProxyONFT721 on the source chain (e.g., ShimmerEVM Testnet): + +```bash +yarn deploy-proxy-onft-smr-Testnet +``` + +Expected log output : + +```bash +npx hardhat run scripts/deploy_proxy_onft721.ts --network shimmerEvmTestnet +Deployed MyProxyONFT721 contract address:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2 +Done in 4.50s. +``` + +#### Deploy `ProxyONFT721` on the destination chain + +You can use the following command to deploy ProxyONFT721 on the destination chain (e.g., BNB Testnet): + +```bash +yarn set-min-dest-gas-onft-bnb-Testnet +``` + +Expected log output : + +```bash +export isForProxy=false && npx hardhat run scripts/set_min_destination_gas.ts --network bnbTestnet +setMinDstGas - isForProxy:false, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10230, minDstGas:150000 +setMinDstGas (packetType 0) tx: 0xce044ded17daa77a8aefc3d39b99c5381216eb4057ddce6253affde6cda2091c +setMinDstGas (packetType 1) tx: 0x3a26ae40ac058099bfd8b85910009a5e5e8b03f16a5f032b572827d48be8f2b0 +Done in 9.34s. +``` + +### Set the Minimum Destination Gas + +#### On the source chain + +You can use the following command to set the minimum destination gas on the `ProxyONFT` contract on the source chain (e.g., ShimmerEVM Testnet): + +```bash +yarn set-min-dest-gas-proxy-onft-smr-Testnet +``` + +Expected log output : + +```bash +export isForProxy=true && npx hardhat run scripts/set_min_destination_gas.ts --network shimmerEvmTestnet +setMinDstGas - isForProxy:true, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10102, minDstGas:150000 +setMinDstGas (packetType 0) tx: 0xcab06e9989448153a4bbc1bb166fc2d33467f3311d1851bf2ff719d982daa613 +setMinDstGas (packetType 1) tx: 0xe78fd3f0bf668fafbc423decd2cf14a27d74543af3ac9daf031f0b278c22ea78 +Done in 6.07s. +``` + +#### On the destination chain + +You can use the following command to set the minimum destination gas on the `ONFT` contract on the destination chain (e.g., BNB Testnet): + +```bash +yarn set-min-dest-gas-onft-bnb-Testnet +``` + +Expected log output : + +```bash +export isForProxy=false && npx hardhat run scripts/set_min_destination_gas.ts --network bnbTestnet +setMinDstGas - isForProxy:false, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10230, minDstGas:150000 +setMinDstGas (packetType 0) tx: 0xce044ded17daa77a8aefc3d39b99c5381216eb4057ddce6253affde6cda2091c +setMinDstGas (packetType 1) tx: 0x3a26ae40ac058099bfd8b85910009a5e5e8b03f16a5f032b572827d48be8f2b0 +Done in 9.34s. +``` + +### Set the batch size limit + +#### On the source chain + +You can use the following command to set batch size limits on the `ProxyONFT` contract on the source chain (e.g., ShimmerEVM Testnet): + +```bash +yarn set-batch-size-limit-proxy-onft-smr-Testnet +``` + +Expected log output : + +```bash +export isForProxy=true && npx hardhat run scripts/set_batch_size_limit.ts --network shimmerEvmTestnet +setBatchSizeLimit - isForProxy:true, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10102, batchSizeLimit:1 +setBatchSizeLimit tx: 0x70c23b3d3d5e94ef82e50944f7eba93fa1fe8db3a5487ac371015e7a14482e75 +Done in 4.28s. +``` + +#### On the destination chain + +You can use the following command to set batch size limits on the `ONFT` contract on the destination chain (e.g., BNB Testnet): + +```bash +yarn set-batch-size-limit-onft-bnb-Testnet +``` + +Expected log output : + +```bash +export isForProxy=false && npx hardhat run scripts/set_batch_size_limit.ts --network bnbTestnet +setBatchSizeLimit - isForProxy:false, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10230, batchSizeLimit:1 +setBatchSizeLimit tx: 0x8cb44c2195ac93da552c646677e6585c95ab172df19463637541933ec70dc9b8 +Done in 4.26s. +``` + +### Set the Trusted Remote + +#### On the source chain + +You can use the following command to set a trusted remote on the `ProxyONFT` contract on the source chain (e.g., ShimmerEVM Testnet): + +```bash +yarn set-remote-proxy-onft-smr-Testnet +``` + +Expected log output : + +```bash +export isForProxy=true && npx hardhat run scripts/set_trusted_remote.ts --network shimmerEvmTestnet +setTrustedRemote - isForProxy:true, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10102 +setTrustedRemote tx: 0xce52c0f25090ef7c1668ef04ff2f6098551c9f56b3ce881d17181bf106457016 +Done in 4.24s. +``` + +##### On the destination chain + +You can use the following command to set a trusted remote on the `ONFT` contract on the destination chain (e.g., BNB Testnet): + +```bash +yarn set-remote-onft-bnb-Testnet +``` + +Expected log output : + +```bash +export isForProxy=false && npx hardhat run scripts/set_trusted_remote.ts --network bnbTestnet +setTrustedRemote - isForProxy:false, proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnRemoteChain:10230 +setTrustedRemote tx: 0x311a0568b5afce7d601df2613f8ff80428d8a4d2f2c91012e0e4a8cbc0aedf59 +Done in 4.88s. +``` + +### Send Origin Tokens From the Source Chain To the Destination Chain + +```bash +yarn send-onft-from-smr-Testnet +``` + +Expected log output: + +```bash +npx hardhat run scripts/send_onft.ts --network shimmerEvmTestnet +sendONFT - proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnSrcChain:10230, lzEndpointIdOnDestChain:10102, gasDropInWeiOnDestChain:0, providedGasLimit:200000, receivingAccountAddress:0x5e812d3128D8fD7CEac08CEca1Cd879E76a6E028, sender: 0x57A4bD139Fb673D364A6f12Df9177A3f686625F3, nftTokenId:2, nftTokenAddress:0xFddbA8928a763679fb8C99d12541B7c6177e9c3c +sendONFT - approve tx: 0xa871bc79e45bf20f33c626044d6e208460c5745ab1f13d476dcbe04e1da7e592 +sendONFT - estimated nativeFee: 158.319172348046094655 +sendONFT - send tx on source chain: 0x72779c7549053194e42bcc78f78cf65e876867f0516dc91f28986c854e652596 +Wait for cross-chain tx finalization by LayerZero ... +sendONFT - received tx on destination chain: 0x2700a9d35c139eb84ba07b75490e6627a30e00bde130e3cb7c1cbb81c0326138 +Done in 53.50s. +``` + +### Send ONFT-Wrapped Tokens Back From the Destination Chain Back To the Origin Chain + +```bash +yarn send-onft-back-from-bnb-Testnet +``` + +Expected log output: + +```bash +npx hardhat run scripts/send_onft_back.ts --network bnbTestnet +sendONFTBack - proxyONFTContractAddress:0x7B0D46219C915e7Ff503C7F83a805c0b2F4ab2F2, onftContractAddress:0xC617A0Bd9DC6093a304515d3dbFF4244333fDeBB, lzEndpointIdOnSrcChain:10230, lzEndpointIdOnDestChain:10102, gasDropInWeiOnDestChain:0, providedGasLimit:200000, receivingAccountAddress:0x57A4bD139Fb673D364A6f12Df9177A3f686625F3, sender: 0x60917645A28258a75836aF63633850c5F3561C1b, nftTokenId:2, nftTokenAddress:0xFddbA8928a763679fb8C99d12541B7c6177e9c3c +sendONFTBack - approve tx: 0xe5bfff108528efdc67e72896845f0ad3e0186b4ed64835e7c5f3552eaab69d99 +sendONFTBack - estimated nativeFee: 0.000498452810033053 +sendONFTBack - send tx on source chain: 0xa43bb5547a5a35730fe183b4d554416a4ea34852e510d21f24d173db75db4e79 +Wait for cross-chain tx finalization by LayerZero ... +sendONFTBack - received tx on destination chain: 0xb05fa2de194153819b26d17893278c485abbaf355fa24f26fbc7a4c759994cde +Done in 212.16s. +``` diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/send-funds-from-L1-to-L2.mdx b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/send-funds-from-L1-to-L2.mdx new file mode 100644 index 00000000000..0b1b47dec7f --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/send-funds-from-L1-to-L2.mdx @@ -0,0 +1,102 @@ +--- +description: How to send funds from L1 to L2. +image: /img/logo/WASP_logo_dark.png +tags: + - configure + - using + - EVM + - Ethereum + - Solidity + - deploy + - hardhat + - metamask + - JSON + - RPC + - how to +--- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import {AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; +import MetamaskButtons from '../../../../_partials/_metamask_buttons.mdx'; +import { Networks } from '@theme/constant'; + +# Send Funds From L1 to L2 + +There are multiple types of assets available on both IOTA L1 and L2, here we discuss a few of them, and how to get them +onto L2. + +:::tip Testnet + +If you want to fund your EVM Testnet account using the EVM Toolkit, please refer to our [Testnet Quickstart Guide](../getting-started/quick-start.mdx) + +::: + +## Fund an Ethereum Account on a IOTA Smart Contracts Chain + +To send EVM transactions, you need to have an Ethereum address that owns tokens on the ISC chain (L2). These tokens will +be used to cover gas fees. + + + + +You can use your [Firefly Wallet](https://firefly.iota.org/) to easily send L1 IOTA or SMR to your L2 IOTA EVM or ShimmerEVM account. + +#### Requirements + +* [IOTA Tokens](/get-started/introduction/iota/iota-token/) or [Shimmer Tokens](/get-started/introduction/shimmer/shimmer-token/) +* [Firefly Wallet](https://firefly.iota.org/) +* [Metamask](https://metamask.io/) + +1. The first thing you will need to do is add the EVM to Metamask by hitting the following button. + + + +2. Once you have added the EVM to Metamask, you can get your address: + + ![Copy your Metamask address](/img/evm/how-tos/get-funds/copy-your-address.png) + +3. Next, you will need to open your [Firefly Wallet](https://firefly.iota.org/) and click on `Send Assets`. + + ![Click send assets](/img/evm/how-tos/get-funds/firefly/select-send-assets.png) + +4. Select the EVM chain you want to use in the network dropdown. + + ![Select the EVM network](/img/evm/how-tos/get-funds/firefly/select-shimmer-evm.png) + +5. Enter the amount of tokens you want to transfer, and the Metamask address from step 2, and click on `Next` + + ![Enter the amount of tokens and metamask address](/img/evm/how-tos/get-funds/firefly/enter-your-desired-amount-and-metamask-address.png) + +6. Review the transaction details and click on `Send`. + + ![Hit Send](/img/evm/how-tos/get-funds/firefly/hit-send.png) + + + + + +You can use your [Bloom Wallet](https://bloomwallet.io/) to easily send L1 base token to your L2 EVM account. + +1. First, you will need to open your [Bloom Wallet](https://firefly.iota.org/) and click on `Send`. + + ![Click send](/img/evm/how-tos/get-funds/bloom/select-send.png) + +2. Select an account with base tokens. + + ![Select an account with base tokens](/img/evm/how-tos/get-funds/bloom/select-the-smr-token.png) + +3. Bloom will automatically create an EVM address for you, so you can send funds to that address from the +EVM dropdown. Alternatively, you can input any other EVM address. + + ![Select you EVM Address](/img/evm/how-tos/get-funds/bloom/enter-the-recipient-address.png) + +4. Enter the amount of base tokens you want to transfer. + + ![Enter the amount of base tokens you want to transfer](/img/evm/how-tos/get-funds/bloom/enter-the-amount.png) + +5. Review the transaction details and click on `Confirm`. + + ![Hit Send](/img/evm/how-tos/get-funds/bloom/review-and-confirm-the-transaction.png) + + + \ No newline at end of file diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/test-smart-contracts.md b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/test-smart-contracts.md new file mode 100644 index 00000000000..c3f2a8aa344 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/how-tos/test-smart-contracts.md @@ -0,0 +1,108 @@ +--- +keywords: +- Smart Contract Testing +- Automated Testing +- Unit Tests +- Integration Tests +- Testing Frameworks +- EVM Testnet +- Solidity Testing +description: Learn how to test smart contracts before deploying them on public networks to avoid vulnerabilities and ensure functionality aligns with requirements using unit, and integration testing, alongside frameworks and testing with the IOTA Sandbox and the EVM Testnet. +--- + +# Testing Smart Contracts + +Once you have deployed a smart contract on a public network, altering it to fix an error can be hard, and it goes +against the principle of immutability, which can create trust issues with users. And, even if it were simple, you could +only fix an error or vulnerability after it is discovered. So, your contract and its users may be at risk if a third +party detects a vulnerability before you do. + +The best way to avoid these overheads and vulnerabilities is to test your contracts thoroughly before deploying them. +You can use [unit](#unit-tests) and [integration](#integration-tests) tests, as well +as [manual testing](#manual-testing), to ensure your contracts behave as expected. + +## Automated Testing + +You can use various tools to automatically test your smart contract’s code and for any error in execution. The great +benefit of automated testing is that it requires minimal human intervention, and it can be built right into your +deployment pipelines. + +Automated testing also allows you to run repetitive and time-consuming tasks without testing each case manually and +avoid human errors, which can happen when you manually input tons of data. + +However, you must be careful, as automated testing can lead to false positives or miss certain edge cases. + +### Unit Tests + +In a nutshell, unit testing ensures that each function and component works correctly by evaluating each independently. +You can use unit tests to ensure that functions return the expected values and modify your contract's state properly. +They should be simple, quick to run and provide helpful feedback if anything goes wrong. This makes them an ideal tool +to ensure your contracts run smoothly after any modifications. + +#### Unit Testing Guidelines + +##### Understand the logic behind your contract’s workflow + +Before you can write any tests, you should understand how your contract is supposed to behave. You should know its +functionalities and how users will access them. Your tests should cover different functions a user may call when +interacting with the contract and check that functions are disabled when they should be. + +#### Evaluate your contract’s assumptions + +It is important to verify that every internal decision the contract takes matches your assumptions on how it should +behave. This forces you to think about edge cases rather than only thinking of the “happy path” you want your users to +take. You can write negative tests to assert how your contract would respond to invalid or malicious inputs. + +##### Measure Code Coverage + +Code coverage is a key metric when it comes to understanding the effectiveness of your tests. It measures the number of +lines, statements, and branches that are actually executed during your unit tests. If you don’t have thorough code +coverage, your test may give what is commonly known as a “false negative”, where your contract passed all your tests, +but your tests didn’t evaluate all the possible vulnerabilities. + +#### Unit Testing Frameworks + +The quality of your unit test will depend on the quality of the tools you use to write and execute them. You should use +a testing framework that is regularly maintained and updated, provides features that are relevant to your contract, and +is popular amongst other developers. + +:::tip Solo + +If you want to test ISC-specific functionalities, like the [magic contract](./core-contracts/introduction.md), you should use +the [Solo Framework](../solo/getting-started.md). + +::: + +* [Waffle](https://ethereum-waffle.readthedocs.io/en/latest/getting-started.html#writing-tests) +* [Remix](https://remix-ide.readthedocs.io/en/latest/unittesting.html#write-tests) +* [Hardhat](https://hardhat.org/hardhat-runner/docs/guides/test-contracts) +* [Brownie](https://eth-brownie.readthedocs.io/en/v1.0.0_a/tests.html) +* [Ape](https://docs.apeworx.io/ape/stable/userguides/testing.html) +* [Foundry](https://book.getfoundry.sh/forge/writing-tests) + +### Integration Tests + +Integration tests are beneficial when your contract adopts a modular architecture or interfaces with other contracts +during its execution. While [unit tests](#unit-tests) focus on testing functions in isolation, trying each cog in the +machine individually, so to speak, integration tests evaluate how these functions work together as a whole, testing the +machine as a whole. You should use integration tests to detect any issues arising from interactions between different +functions in your contracts' cross-contract calls and ensure that inherited or extended functions are working as +expected. + +#### Tools + +You can use the [EVM Testnet](/build/networks-endpoints/#shimmerevm-testnet) to conduct integration tests without +incurring any fees or the [IOTA Sandbox](/iota-sandbox/getting-started/) if you want to run the tests locally. + +## Manual Testing + +Once you have a complete batch of [automated tests](#automated-testing), manually testing your contract to ensure it +behaves as expected in the real world is still good practice. However, to avoid incurring fees or deploying a faulty +contract, you can manually test your contract using a sandboxed local network and the EVM Testnet. + +Testing using the [IOTA Sandbox](/iota-sandbox/getting-started/) serves well for the first stage of automated and manual +integration tests, as you have complete control over the entire local network. Once you are confident about how your +contract behaves locally, you can deploy and test on the [EVM Testnet](/build/networks-endpoints/#shimmerevm-testnet), +which replicates the IOTA EVM and ShimmerEVM networks, but also enables cost and risk-free interactions. + + diff --git a/docs/content/guides/developer/layer-2-smart-contracts/introduction.md b/docs/content/guides/developer/layer-2-smart-contracts/introduction.md new file mode 100644 index 00000000000..b3811792692 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/introduction.md @@ -0,0 +1,74 @@ +--- +description: 'The current release of IOTA Smart Contracts also has experimental support for EVM/Solidity, providing +limited compatibility with existing smart contracts and tooling from other EVM based chains like Ethereum.' +image: /img/logo/WASP_logo_dark.png +tags: + + - EVM + - Solidity + - smart contracts + - Ethereum + - explanation + +--- +import OnOffLedgerRequest from './_partials/_on_off_ledger_request.md'; + +# Introduction + +Smart contracts are deterministic applications that run on a distributed network with multiple +[validators](explanations/validators.md) that execute and validate the same code. +Their deterministic and distributed nature makes them predictable, stable and trustworthy. + +## Scalable Smart Contracts + +Due to the distributed nature of smart contracts, i.e. they run on a network of validators instead of a single computer, +the execution of smart contract is resource intensive as it has to deal with the overhead of the communication between validators in the network. +This can lead to relatively high [fees](#gas) for smart contract execution, as well as scalability issues when running on +a single blockchain. However, the IOTA Smart Contract Protocol allows **many blockchains that execute smart contracts to +run in parallel** and communicate with one another, therefore solving the scalability problem. Enabling interoperability and horizontal scaling of dApps. + +At the same time, ISC provides advanced means of communication between its chains and preserves the ability to create +complex, composed smart contracts. + +## ISC Architecture + +IOTA Smart Contracts (ISC) function as a Layer 2 extension to the IOTA Multi-Asset Ledger. +As validator nodes execute the smart contracts, they tally these state changes and write them into the chain. +In turn ISC chains, each with their state and smart contracts, update their state collectively and interact with Layer 1 +and other L2 chains, offering a sophisticated multi-chain architecture. + +![IOTA Smart Contacts multichain architecture](/img/multichain.png 'Click to see the full-size image.') + +_IOTA Smart Contacts multichain architecture._ + +[Explore the comprehensive overview of IOTA Smart Contracts in the ISC white paper](https://files.iota.org/papers/ISC_WP_Nov_10_2021.pdf). + +## Supported VMs + +The IOTA Smart Contracts currently +supports [EVM/Solidity](getting-started/languages-and-vms.md#evmsolidity-based-smart-contracts) +smart contracts, as well as an **experimental** [Wasm VM](getting-started/languages-and-vms.md#wasm-vm-for-isc). + +## Sandbox Interface + +ISC Smart contracts can access the [Sandbox interface](explanations/sandbox.md). +This interface provides access to the chain state, native assets, allows interaction with other contracts/chains, as +well as various utilities like cryptographic functions and event dispatching. + +![Sandbox](/img/sandbox.png) + +## Calling a Smart Contract + +### Entry Points and Requests + +Smart contracts are activated through entry points, similar to function calls. Entry points can be view-only or allow state +modifications. They are triggered by requests, signed by senders. Smart contracts on the same chain can +synchronously invoke each other, ensuring deterministic results. However, requests between chains are asynchronous and +may involve delays. + +### Gas + +Running a request consumes 'gas'. Gas units are a measurement of "how expensive" a computation is to execute. You can specify a `GasBudget` +for each request, with costs charged to your on-chain account. + + diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/access.mdx b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/access.mdx new file mode 100644 index 00000000000..a9c799a32a2 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/access.mdx @@ -0,0 +1,37 @@ +--- +description: "This article explains how to define access controls for functions using the optional 'access' subsection in the schema definition file." +tags: + - Access Control + - Schema Tool + - Smart Contract + - AgentID + - Function Access +image: /img/logo/WASP_logo_dark.png +--- + +# Limit Access + +You can define function access controls through the optional `access` subsection in the schema definition file. +By default, functions are accessible to everyone. However, when specified, the `access` identifier restricts who can +call a function. + +## Access Identifiers + +You can set access identifiers with **one** of the following options: + +- `self`: Restricts access to the smart contract itself. +- `chain`: Allows only the chain owner to invoke the function. +- Other: Specify an AgentID or AgentID[] variable in state storage, controlling the agent(s) permitted to call the + function. + You should provide a mechanism to initialize and manage this variable. + +The [Schema Tool](usage.mdx) handles the auto-generation of the code for access verification. + +## Usage Examples + +You can find examples in the schema definition file where the `owner` state variable operates as an access identifier. +Functions such as `init` initialize the state variable, while `setOwner` can modify ownership, +enhancing the security by limiting function access to the current owner. + +Remember to tailor access identifiers to individual functions as required, +and establish multiple identifiers if necessary. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/call.mdx b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/call.mdx new file mode 100644 index 00000000000..3a0f26d0df1 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/call.mdx @@ -0,0 +1,178 @@ +--- +description: "Explore how synchronous function calls work between smart contracts, highlighting the role of function descriptors in parameter and token passage, and understanding the ISC host's role in this procedure." +tags: + - Synchronous Calls + - Smart Contracts + - Function Descriptors + - ISC Host + - Function Parameters + - Smart Contract Memory +image: /img/logo/WASP_logo_dark.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Call Functions + +Synchronous function calls between smart contracts act very similar to how normal function calls work in any programming language, +but with a slight twist. +With normal function calls, you share all the global memory that you can access with every function that you call. +However, when calling a smart contract function, +you can only access the memory assigned to that specific smart contract. + +## How Synchronous Calls Operate + +### Data Sharing + +If you want to share data between smart contracts, you will need to use: + +- Function [parameters](params.mdx) +- [Return](results.mdx) values + +## The ISC Host Role + +Ensuring smooth synchronous calls between contracts on the same chain, the ISC host: + +- Recognizes all contracts functioning on a chain. +- Directs the call appropriately to the destined contract function using function descriptors. + +### Function Descriptors + +Function descriptors allow: + +- Specification of call parameters via the [Params](params.mdx) proxy. +- Function invocation through the `func` interface. +- Passing tokens to non-[View](views.mdx) function calls within the same chain. + +:::note + +The only way to call a function and properly pass tokens to it within the same chain is through the function descriptor. +Otherwise, the allowance() function will not register any incoming tokens. + +::: + +### Call Process + +During a call: + +- The initiator function pauses and awaits the completion of the called function. +- Post-completion, retrieves potential returned values through the [Results](results.mdx) proxy. + +### Calling From View Functions + +When a view function initiates a call: + +- It can only reach out to other [view](views.mdx) functions. +- The `ScFuncs` interface mandates an `ScViewContext` for the constructor creating the function descriptor. + +## Usage Example + +Here's how a smart contract would tell a `dividend` contract on the same chain to divide the 1000 tokens it passes to the function: + + + + + +```go +f := dividend.ScFuncs.Divide(ctx) +f.Func.TransferBaseTokens(1000).Call() +``` + + + + +```rust +let f = dividend::ScFuncs::divide(ctx); +f.func.transfer_base_tokens(1000).call(); +``` + + + + +```ts +let f = dividend.ScFuncs.divide(ctx); +f.func.transferBaseTokens(1000).call(); +``` + + + + +And here is how a smart contract would ask a `dividend` contract on the same chain to +return the dispersion factor for a specific address: + + + + + +```go +f := dividend.ScFuncs.GetFactor(ctx) +f.Params.Address().SetValue(address) +f.Func.Call() +factor := f.Results.Factor().Value() +``` + + + + +```rust +let f = dividend::ScFuncs::get_factor(ctx); +f.params.address().set_value(&address); +f.func.call(); +let factor = f.results.factor().value(); +``` + + + + +```ts +let f = dividend.ScFuncs.getFactor(ctx); +f.params.address().setValue(address); +f.func.call(); +let factor = f.results.factor().value(); +``` + + + + +1. Create a function descriptor for the desired function. +2. Use the [Params](params.mdx) proxy in the descriptor to set its parameters. +3. Direct the `func` member of the descriptor to call the associated function +4. Use the [Results](results.mdx) proxy in the descriptor to retrieve its results. + +The function descriptors assume that the function to be called is associated with the +default Hname of the contract, in this case ScHname::new("dividend"). If you deployed the +contract that contains the function you want to call under a different name, then you +would have to provide its associated Hname to the `func` member through the of_contract() +member function like this: + + + + + +```go +altContract := NewScHname("alternateName") +f := dividend.ScFuncs.Divide(ctx) +f.Func.OfContract(altContract).TransferBaseTokens(1000).Call() +``` + + + + +```rust +let alt_contract = ScHname::new("alternateName"); +let f = dividend::ScFuncs::divide(ctx); +f.func.of_contract(alt_contract).transfer_base_tokens(1000).call(); +``` + + + + +```ts +let altContract = ScHname.fromString('alternateName'); +let f = dividend.ScFuncs.divide(ctx); +f.func.ofContract(altContract).transferBaseTokens(1000).call(); +``` + + + diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/events.mdx b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/events.mdx new file mode 100644 index 00000000000..02bd5174e73 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/events.mdx @@ -0,0 +1,317 @@ +--- +description: "This article outlines how to trigger events in smart contracts utilizing ISC sandbox's ScFuncContext and the Schema Tool for structured events." +tags: + - Smart Contracts + - ISC Sandbox + - Schema Tool + - Event-driven + - Call Context + - ScFuncContext + - Event Triggering +image: /img/logo/WASP_logo_dark.png +--- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Trigger Events + +Smart contracts operate in a confined environment but need a mechanism to interact with users. +A solution to this is triggering events, which is facilitated through smart contracts. + +## ISC Sandbox Interface + +The `ScFuncContext` [Call Context](../../explanations/context.mdx) in ISC _Sandbox_ has an `event()` function to support event triggering. +This function takes a text string parameter, requiring creators and users to maintain and understand the chosen format. +However, this setup is prone to errors and inconsistency due to the arbitrary nature of the text strings used. + +## Structured Events with Schema Tool + +To mitigate issues stemming from the rudimentary interface, +use the [Schema Tool](usage.mdx) to define structured events, +making event creation and handling more consistent and less error-prone. + +This tool allows you to establish structured events that are integrated into all Func function contexts. +Note that events: + +- Can only be triggered within a Func +- Become part of the smart contract's state +- Are logged in the core `blocklog` contract +- Cannot be triggered within a View + +## Event Structure + +Define each event in the `events` section of the schema definition file. +This setup ensures that events are encoded consistently, +utilizing a function that automatically formats the event string with the event name, timestamp, and parameter fields, +delimited by vertical bars. +This structured approach facilitates streamlined, error-resistant event triggering. + +### Example + +Here is the `events` section that can be found in the demo `fairroulette` smart contract: + + + + +```yaml +events: + bet: + address: Address # address of better + amount: Uint64 # amount of tokens to bet + number: Uint16 # number to bet on + payout: + address: Address # address of winner + amount: Uint64 # amount of tokens won + round: + number: Uint32 # current betting round number + start: + stop: + winner: + number: Uint16 # the winning number +``` + + + + +The [Schema Tool](usage.mdx) will generate `events.xx` which contains the following code +for the `FairRouletteEvents` struct: + + + + + +```go +package fairroulette + +import "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib" +import "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/wasmtypes" + +type FairRouletteEvents struct { +} + +func (e FairRouletteEvents) Bet( + // address of better + address wasmtypes.ScAddress, + // amount of tokens to bet + amount uint64, + // number to bet on + number uint16, +) { + evt := wasmlib.NewEventEncoder("fairroulette.bet") + evt.Encode(wasmtypes.AddressToString(address)) + evt.Encode(wasmtypes.Uint64ToString(amount)) + evt.Encode(wasmtypes.Uint16ToString(number)) + evt.Emit() +} + +func (e FairRouletteEvents) Payout( + // address of winner + address wasmtypes.ScAddress, + // amount of tokens won + amount uint64, +) { + evt := wasmlib.NewEventEncoder("fairroulette.payout") + evt.Encode(wasmtypes.AddressToString(address)) + evt.Encode(wasmtypes.Uint64ToString(amount)) + evt.Emit() +} + +func (e FairRouletteEvents) Round( + // current betting round number + number uint32, +) { + evt := wasmlib.NewEventEncoder("fairroulette.round") + evt.Encode(wasmtypes.Uint32ToString(number)) + evt.Emit() +} + +func (e FairRouletteEvents) Start() { + evt := wasmlib.NewEventEncoder("fairroulette.start") + evt.Emit() +} + +func (e FairRouletteEvents) Stop() { + evt := wasmlib.NewEventEncoder("fairroulette.stop") + evt.Emit() +} + +func (e FairRouletteEvents) Winner( + // the winning number + number uint16, +) { + evt := wasmlib.NewEventEncoder("fairroulette.winner") + evt.Encode(wasmtypes.Uint16ToString(number)) + evt.Emit() +} +``` + + + + +```rust +use wasmlib::*; + +pub struct FairRouletteEvents { +} + +impl FairRouletteEvents { + + pub fn bet(&self, + // address of better + address: &ScAddress, + // amount of tokens to bet + amount: u64, + // number to bet on + number: u16, + ) { + let mut evt = EventEncoder::new("fairroulette.bet"); + evt.encode(&address_to_string(&address)); + evt.encode(&uint64_to_string(amount)); + evt.encode(&uint16_to_string(number)); + evt.emit(); + } + + pub fn payout(&self, + // address of winner + address: &ScAddress, + // amount of tokens won + amount: u64, + ) { + let mut evt = EventEncoder::new("fairroulette.payout"); + evt.encode(&address_to_string(&address)); + evt.encode(&uint64_to_string(amount)); + evt.emit(); + } + + pub fn round(&self, + // current betting round number + number: u32, + ) { + let mut evt = EventEncoder::new("fairroulette.round"); + evt.encode(&uint32_to_string(number)); + evt.emit(); + } + + pub fn start(&self) { + let mut evt = EventEncoder::new("fairroulette.start"); + evt.emit(); + } + + pub fn stop(&self) { + let mut evt = EventEncoder::new("fairroulette.stop"); + evt.emit(); + } + + pub fn winner(&self, + // the winning number + number: u16, + ) { + let mut evt = EventEncoder::new("fairroulette.winner"); + evt.encode(&uint16_to_string(number)); + evt.emit(); + } +} +``` + + + + +```ts +import * as wasmlib from 'wasmlib'; +import * as wasmtypes from 'wasmlib/wasmtypes'; + +export class FairRouletteEvents { + bet( + // address of better + address: wasmtypes.ScAddress, + // amount of tokens to bet + amount: u64, + // number to bet on + number: u16, + ): void { + const evt = new wasmlib.EventEncoder('fairroulette.bet'); + evt.encode(wasmtypes.addressToString(address)); + evt.encode(wasmtypes.uint64ToString(amount)); + evt.encode(wasmtypes.uint16ToString(number)); + evt.emit(); + } + + payout( + // address of winner + address: wasmtypes.ScAddress, + // amount of tokens won + amount: u64, + ): void { + const evt = new wasmlib.EventEncoder('fairroulette.payout'); + evt.encode(wasmtypes.addressToString(address)); + evt.encode(wasmtypes.uint64ToString(amount)); + evt.emit(); + } + + round( + // current betting round number + number: u32, + ): void { + const evt = new wasmlib.EventEncoder('fairroulette.round'); + evt.encode(wasmtypes.uint32ToString(number)); + evt.emit(); + } + + start(): void { + const evt = new wasmlib.EventEncoder('fairroulette.start'); + evt.emit(); + } + + stop(): void { + const evt = new wasmlib.EventEncoder('fairroulette.stop'); + evt.emit(); + } + + winner( + // the winning number + number: u16, + ): void { + const evt = new wasmlib.EventEncoder('fairroulette.winner'); + evt.encode(wasmtypes.uint16ToString(number)); + evt.emit(); + } +} +``` + + + + +Notice how the generated functions use the WasmLib EventEncoder to encode the parameters +into a single string before emitting it. Here is the way in which `fairroulette` emits the +`bet` event in its smart contract code: + + + + + +```go + f.Events.Bet(bet.Better.Address(), bet.Amount, bet.Number) +``` + + + + +```rust + f.events.bet(&bet.better.address(), bet.amount, bet.number); +``` + + + + +```ts +f.events.bet(bet.better.address(), bet.amount, bet.number); +``` + + + + +The smart contract client code can define handler functions to listen in to the event +stream and respond to any events it deems noteworthy. The [Schema Tool](usage.mdx) will +automatically generate the necessary client side code that properly listens for the +events, parses the event strings into a type-safe structure, and passes this structure to +the corresponding handler function. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/funcdesc.mdx b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/funcdesc.mdx new file mode 100644 index 00000000000..bb4f18ee046 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/funcdesc.mdx @@ -0,0 +1,404 @@ +--- +tags: + - descriptor + - view + - access + - contract functions + - schema tool + +description: The schema tool provides us with an easy way to get access to smart contract functions through function descriptors, which allow you to initiate the function by calling it synchronously, or posting a request to run it asynchronously. + +image: /img/logo/WASP_logo_dark.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Add Function Descriptors + +You can use the [Schema Tool](usage.mdx) to access, and initiate smart contract functions seamlessly using +function descriptors. +These descriptors allow you to access optional [Params](params.mdx) and [Results](results.mdx) maps through strict +compile-time checked interfaces. + +## Function Descriptors Overview + +Function descriptors are structures that: + +- Offer access to the optional [Params](params.mdx) and [Results](results.mdx) maps. +- Allow synchronous or asynchronous initiation of functions through [`call()`](call.mdx) or [`post()`](post.mdx) requests. + +## The Schema Tool in Action + +The Schema Tool performs the following tasks: + +### 1. **Generate Specific Descriptors**: + +- For each function (`func`) and view. +- The outcome: Structs granting access to [Params](params.mdx) or [Results](results.mdx) maps, wherever specified. + +## 2. **Create the `ScFuncs` Interface**: + +- Facilitate the creation and initialization of each function descriptor. +- Incorporate a member function for every func or view to craft their respective function descriptor properly. + + + + + +```go +package dividend + +import "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib" + +type DivideCall struct { + Func *wasmlib.ScFunc +} + +type InitCall struct { + Func *wasmlib.ScInitFunc + Params MutableInitParams +} + +type MemberCall struct { + Func *wasmlib.ScFunc + Params MutableMemberParams +} + +type SetOwnerCall struct { + Func *wasmlib.ScFunc + Params MutableSetOwnerParams +} + +type GetFactorCall struct { + Func *wasmlib.ScView + Params MutableGetFactorParams + Results ImmutableGetFactorResults +} + +type GetOwnerCall struct { + Func *wasmlib.ScView + Results ImmutableGetOwnerResults +} + +type Funcs struct{} + +var ScFuncs Funcs + +// divide tokens over members +func (sc Funcs) Divide(ctx wasmlib.ScFuncCallContext) *DivideCall { + return &DivideCall{Func: wasmlib.NewScFunc(ctx, HScName, HFuncDivide)} +} + +func (sc Funcs) Init(ctx wasmlib.ScFuncCallContext) *InitCall { + f := &InitCall{Func: wasmlib.NewScInitFunc(ctx, HScName, HFuncInit)} + f.Params.proxy = wasmlib.NewCallParamsProxy(&f.Func.ScView) + return f +} + +func (sc Funcs) Member(ctx wasmlib.ScFuncCallContext) *MemberCall { + f := &MemberCall{Func: wasmlib.NewScFunc(ctx, HScName, HFuncMember)} + f.Params.proxy = wasmlib.NewCallParamsProxy(&f.Func.ScView) + return f +} + +func (sc Funcs) SetOwner(ctx wasmlib.ScFuncCallContext) *SetOwnerCall { + f := &SetOwnerCall{Func: wasmlib.NewScFunc(ctx, HScName, HFuncSetOwner)} + f.Params.proxy = wasmlib.NewCallParamsProxy(&f.Func.ScView) + return f +} + +func (sc Funcs) GetFactor(ctx wasmlib.ScViewCallContext) *GetFactorCall { + f := &GetFactorCall{Func: wasmlib.NewScView(ctx, HScName, HViewGetFactor)} + f.Params.proxy = wasmlib.NewCallParamsProxy(f.Func) + wasmlib.NewCallResultsProxy(f.Func, &f.Results.proxy) + return f +} + +func (sc Funcs) GetOwner(ctx wasmlib.ScViewCallContext) *GetOwnerCall { + f := &GetOwnerCall{Func: wasmlib.NewScView(ctx, HScName, HViewGetOwner)} + wasmlib.NewCallResultsProxy(f.Func, &f.Results.proxy) + return f +} +``` + + + + + +```rust +use wasmlib::*; +use crate::*; + +pub struct DivideCall { + pub func: ScFunc, +} + +pub struct InitCall { + pub func: ScInitFunc, + pub params: MutableInitParams, +} + +pub struct MemberCall { + pub func: ScFunc, + pub params: MutableMemberParams, +} + +pub struct SetOwnerCall { + pub func: ScFunc, + pub params: MutableSetOwnerParams, +} + +pub struct GetFactorCall { + pub func: ScView, + pub params: MutableGetFactorParams, + pub results: ImmutableGetFactorResults, +} + +pub struct GetOwnerCall { + pub func: ScView, + pub results: ImmutableGetOwnerResults, +} + +pub struct ScFuncs { +} + +impl ScFuncs { + // divide tokens over members + pub fn divide(_ctx: &dyn ScFuncCallContext) -> DivideCall { + DivideCall { + func: ScFunc::new(HSC_NAME, HFUNC_DIVIDE), + } + } + + pub fn init(_ctx: &dyn ScFuncCallContext) -> InitCall { + let mut f = InitCall { + func: ScInitFunc::new(HSC_NAME, HFUNC_INIT), + params: MutableInitParams { proxy: Proxy::nil() }, + }; + ScInitFunc::link_params(&mut f.params.proxy, &f.func); + f + } + + pub fn member(_ctx: &dyn ScFuncCallContext) -> MemberCall { + let mut f = MemberCall { + func: ScFunc::new(HSC_NAME, HFUNC_MEMBER), + params: MutableMemberParams { proxy: Proxy::nil() }, + }; + ScFunc::link_params(&mut f.params.proxy, &f.func); + f + } + + pub fn set_owner(_ctx: &dyn ScFuncCallContext) -> SetOwnerCall { + let mut f = SetOwnerCall { + func: ScFunc::new(HSC_NAME, HFUNC_SET_OWNER), + params: MutableSetOwnerParams { proxy: Proxy::nil() }, + }; + ScFunc::link_params(&mut f.params.proxy, &f.func); + f + } + + pub fn get_factor(_ctx: &dyn ScViewCallContext) -> GetFactorCall { + let mut f = GetFactorCall { + func: ScView::new(HSC_NAME, HVIEW_GET_FACTOR), + params: MutableGetFactorParams { proxy: Proxy::nil() }, + results: ImmutableGetFactorResults { proxy: Proxy::nil() }, + }; + ScView::link_params(&mut f.params.proxy, &f.func); + ScView::link_results(&mut f.results.proxy, &f.func); + f + } + + pub fn get_owner(_ctx: &dyn ScViewCallContext) -> GetOwnerCall { + let mut f = GetOwnerCall { + func: ScView::new(HSC_NAME, HVIEW_GET_OWNER), + results: ImmutableGetOwnerResults { proxy: Proxy::nil() }, + }; + ScView::link_results(&mut f.results.proxy, &f.func); + f + } +} +``` + + + + +```ts +import * as wasmlib from 'wasmlib'; +import * as sc from './index'; + +export class DivideCall { + func: wasmlib.ScFunc; + public constructor(ctx: wasmlib.ScFuncCallContext) { + this.func = new wasmlib.ScFunc(ctx, sc.HScName, sc.HFuncDivide); + } +} + +export class DivideContext { + state: sc.MutableDividendState = new sc.MutableDividendState( + wasmlib.ScState.proxy(), + ); +} + +export class InitCall { + func: wasmlib.ScInitFunc; + params: sc.MutableInitParams = new sc.MutableInitParams( + wasmlib.ScView.nilProxy, + ); + public constructor(ctx: wasmlib.ScFuncCallContext) { + this.func = new wasmlib.ScInitFunc(ctx, sc.HScName, sc.HFuncInit); + } +} + +export class InitContext { + params: sc.ImmutableInitParams = new sc.ImmutableInitParams( + wasmlib.paramsProxy(), + ); + state: sc.MutableDividendState = new sc.MutableDividendState( + wasmlib.ScState.proxy(), + ); +} + +export class MemberCall { + func: wasmlib.ScFunc; + params: sc.MutableMemberParams = new sc.MutableMemberParams( + wasmlib.ScView.nilProxy, + ); + public constructor(ctx: wasmlib.ScFuncCallContext) { + this.func = new wasmlib.ScFunc(ctx, sc.HScName, sc.HFuncMember); + } +} + +export class MemberContext { + params: sc.ImmutableMemberParams = new sc.ImmutableMemberParams( + wasmlib.paramsProxy(), + ); + state: sc.MutableDividendState = new sc.MutableDividendState( + wasmlib.ScState.proxy(), + ); +} + +export class SetOwnerCall { + func: wasmlib.ScFunc; + params: sc.MutableSetOwnerParams = new sc.MutableSetOwnerParams( + wasmlib.ScView.nilProxy, + ); + public constructor(ctx: wasmlib.ScFuncCallContext) { + this.func = new wasmlib.ScFunc(ctx, sc.HScName, sc.HFuncSetOwner); + } +} + +export class SetOwnerContext { + params: sc.ImmutableSetOwnerParams = new sc.ImmutableSetOwnerParams( + wasmlib.paramsProxy(), + ); + state: sc.MutableDividendState = new sc.MutableDividendState( + wasmlib.ScState.proxy(), + ); +} + +export class GetFactorCall { + func: wasmlib.ScView; + params: sc.MutableGetFactorParams = new sc.MutableGetFactorParams( + wasmlib.ScView.nilProxy, + ); + results: sc.ImmutableGetFactorResults = new sc.ImmutableGetFactorResults( + wasmlib.ScView.nilProxy, + ); + public constructor(ctx: wasmlib.ScViewCallContext) { + this.func = new wasmlib.ScView(ctx, sc.HScName, sc.HViewGetFactor); + } +} + +export class GetFactorContext { + params: sc.ImmutableGetFactorParams = new sc.ImmutableGetFactorParams( + wasmlib.paramsProxy(), + ); + results: sc.MutableGetFactorResults = new sc.MutableGetFactorResults( + wasmlib.ScView.nilProxy, + ); + state: sc.ImmutableDividendState = new sc.ImmutableDividendState( + wasmlib.ScState.proxy(), + ); +} + +export class GetOwnerCall { + func: wasmlib.ScView; + results: sc.ImmutableGetOwnerResults = new sc.ImmutableGetOwnerResults( + wasmlib.ScView.nilProxy, + ); + public constructor(ctx: wasmlib.ScViewCallContext) { + this.func = new wasmlib.ScView(ctx, sc.HScName, sc.HViewGetOwner); + } +} + +export class GetOwnerContext { + results: sc.MutableGetOwnerResults = new sc.MutableGetOwnerResults( + wasmlib.ScView.nilProxy, + ); + state: sc.ImmutableDividendState = new sc.ImmutableDividendState( + wasmlib.ScState.proxy(), + ); +} + +export class ScFuncs { + // divide tokens over members + static divide(ctx: wasmlib.ScFuncCallContext): DivideCall { + return new DivideCall(ctx); + } + + static init(ctx: wasmlib.ScFuncCallContext): InitCall { + const f = new InitCall(ctx); + f.params = new sc.MutableInitParams(wasmlib.newCallParamsProxy(f.func)); + return f; + } + + static member(ctx: wasmlib.ScFuncCallContext): MemberCall { + const f = new MemberCall(ctx); + f.params = new sc.MutableMemberParams(wasmlib.newCallParamsProxy(f.func)); + return f; + } + + static setOwner(ctx: wasmlib.ScFuncCallContext): SetOwnerCall { + const f = new SetOwnerCall(ctx); + f.params = new sc.MutableSetOwnerParams(wasmlib.newCallParamsProxy(f.func)); + return f; + } + + static getFactor(ctx: wasmlib.ScViewCallContext): GetFactorCall { + const f = new GetFactorCall(ctx); + f.params = new sc.MutableGetFactorParams( + wasmlib.newCallParamsProxy(f.func), + ); + f.results = new sc.ImmutableGetFactorResults( + wasmlib.newCallResultsProxy(f.func), + ); + return f; + } + + static getOwner(ctx: wasmlib.ScViewCallContext): GetOwnerCall { + const f = new GetOwnerCall(ctx); + f.results = new sc.ImmutableGetOwnerResults( + wasmlib.newCallResultsProxy(f.func), + ); + return f; + } +} +``` + + + + +## `dividend` Example - Generated Code + +In the `dividend` example in `contract.xx`, specific structs for [Funcs and Views](../../schema/proxies.mdx) are created. +Here's how they operate: + +### Access + +- Via the `func` member within each struct. +- The `func` member type: Either `ScFunc` or `ScView`, contingent on whether it’s a function or a view. + +### Utilization + +- The `func` member is used to initiate function calls in various ways. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/funcs.mdx b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/funcs.mdx new file mode 100644 index 00000000000..0c48c6c85ed --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/funcs.mdx @@ -0,0 +1,82 @@ +--- +tags: + - functions + - views + - state + - access + - params + - results + +image: /img/logo/WASP_logo_dark.png +description: The code generated for Funcs will be able to inspect and modify the smart contract state, whereas the code generated for Views will only be able to inspect the state. +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Define Functions + +Here is the full schema definition file for the `dividend` example. We will now focus on +its [`funcs` and `views` sections](../../explanations/context.mdx). Since they are structured identically we will only need +to explain the layout of these sections once. + + + + +```yaml +name: Dividend +description: Simple dividend smart contract +structs: {} +typedefs: {} +state: + memberList: Address[] # array with all the recipients of this dividend + + # factors per member + + members: map[Address]Uint64 # map with all the recipient factors of this dividend + owner: AgentID # owner of contract, the only one who can call 'member' func + totalFactor: Uint64 # sum of all recipient factors +funcs: + # divide tokens over members + divide: {} + init: + params: + owner: AgentID? # optional owner of contract, defaults to contract creator + member: + access: owner # only defined owner of contract can add members + params: + address: Address # address of dividend recipient + factor: Uint64 # relative division factor + setOwner: + access: owner # only defined owner of contract can change owner + params: + owner: AgentID # new owner of smart contract +views: + getFactor: + params: + address: Address # address of dividend recipient + results: + factor: Uint64 # relative division factor + getOwner: + results: + owner: AgentID # current owner of this smart contract +``` + + + + + +As you can see each of the `funcs` and `views` sections defines their functions in the +same way. The only resulting difference is in the way the [Schema Tool](usage.mdx) +generates code for them: + +- The code generated for Funcs will be able to inspect and modify the smart contract state. +- The code generated for Views will only be able to inspect the state. + +Functions are defined as named subsections in the schema definition file. The name of the +subsection will become the name of the function. In turn, there can be 3 optional +subsections under each function subsection. + +- [`access`](access.mdx) indicates who is allowed to access the function. +- `params` holds the field definitions that describe the function parameters. +- `results` holds the field definitions that describe the function results. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/init.mdx b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/init.mdx new file mode 100644 index 00000000000..3425089182c --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/init.mdx @@ -0,0 +1,269 @@ +--- +tags: + - init + - initialization + - owner + - initial state + - smart contract creator + - one-time + - contract deployment + +description: The init function will automatically be called immediately after the first time the contract has been deployed to the VM. This is a one-time initialization call, meant to be performed by the contract deployment mechanism. +image: /img/logo/WASP_logo_dark.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Initialize a Smart Contract + +Smart contracts begin with a blank slate. You can define an initial state through the `init()` function. +This function is vital for setting configurations at the time of deployment. + +## Features of the `init()` Function + +### One-time Call + +Triggered automatically post-deployment, **it can only be used once** to set the initial configurations. + +### Security + +The ISC ensures the `init()` function is inaccessible after its initial execution, +safeguarding it from unauthorized accesses. + +### Necessity For a Separate Configuration Function + +To facilitate reconfiguration in the future, develop a distinct configuration function with proper access controls. + +## Usage Example + +To show how creating a smart contract with WasmLib works, we will slowly start fleshing +out the smart contract functions of the `dividend` example in this tutorial. Here is the +first part of the code that implements it, which contains the `init()` function: + + + + + +```go +// This example implements 'dividend', a simple smart contract that will +// automatically disperse iota tokens which are sent to the contract to a group +// of member accounts according to predefined division factors. The intent is +// to showcase basic functionality of WasmLib through a minimal implementation +// and not to come up with a complete robust real-world solution. +// Note that we have drawn sometimes out constructs that could have been done +// in a single line over multiple statements to be able to properly document +// step by step what is happening in the code. We also unnecessarily annotate +// all 'var' statements with their assignment type to improve understanding. + +//nolint:revive,goimports +package dividend + +import ( + "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib" + "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/wasmtypes" +) + +// 'init' is used as a way to initialize a smart contract. It is an optional +// function that will automatically be called upon contract deployment. In this +// case we use it to initialize the 'owner' state variable so that we can later +// use this information to prevent non-owners from calling certain functions. +// The 'init' function takes a single optional parameter: +// - 'owner', which is the agent id of the entity owning the contract. +// When this parameter is omitted the owner will default to the contract creator. +func funcInit(ctx wasmlib.ScFuncContext, f *InitContext) { + // The schema tool has already created a proper InitContext for this function that + // allows us to access call parameters and state storage in a type-safe manner. + + // First we set up a default value for the owner in case the optional 'owner' + // parameter was omitted. We use the agent that sent the deploy request. + var owner wasmtypes.ScAgentID = ctx.RequestSender() + + // Now we check if the optional 'owner' parameter is present in the params map. + if f.Params.Owner().Exists() { + // Yes, it was present, so now we overwrite the default owner with + // the one specified by the 'owner' parameter. + owner = f.Params.Owner().Value() + } + + // Now that we have sorted out which agent will be the owner of this contract + // we will save this value in the 'owner' variable in state storage on the host. + // Read the documentation on schema.yaml to understand why this state variable is + // supported at compile-time by code generated from schema.yaml by the schema tool. + f.State.Owner().SetValue(owner) +} +``` + + + + +```rust +// This example implements 'dividend', a simple smart contract that will +// automatically disperse iota tokens which are sent to the contract to a group +// of member accounts according to predefined division factors. The intent is +// to showcase basic functionality of WasmLib through a minimal implementation +// and not to come up with a complete robust real-world solution. +// Note that we have drawn sometimes out constructs that could have been done +// in a single line over multiple statements to be able to properly document +// step by step what is happening in the code. We also unnecessarily annotate +// all 'let' statements with their assignment type to improve understanding. + +use wasmlib::*; + +use crate::*; + +// 'init' is used as a way to initialize a smart contract. It is an optional +// function that will automatically be called upon contract deployment. In this +// case we use it to initialize the 'owner' state variable so that we can later +// use this information to prevent non-owners from calling certain functions. +// The 'init' function takes a single optional parameter: +// - 'owner', which is the agent id of the entity owning the contract. +// When this parameter is omitted the owner will default to the contract creator. +pub fn func_init(ctx: &ScFuncContext, f: &InitContext) { + // The schema tool has already created a proper InitContext for this function that + // allows us to access call parameters and state storage in a type-safe manner. + + // First we set up a default value for the owner in case the optional 'owner' + // parameter was omitted. We use the agent that sent the deploy request. + let mut owner: ScAgentID = ctx.request_sender(); + + // Now we check if the optional 'owner' parameter is present in the params map. + if f.params.owner().exists() { + // Yes, it was present, so now we overwrite the default owner with + // the one specified by the 'owner' parameter. + owner = f.params.owner().value(); + } + + // Now that we have sorted out which agent will be the owner of this contract + // we will save this value in the 'owner' variable in state storage on the host. + // Read the documentation on schema.yaml to understand why this state variable is + // supported at compile-time by code generated from schema.yaml by the schema tool. + f.state.owner().set_value(&owner); +} +``` + + + + +```ts +// This example implements 'dividend', a simple smart contract that will +// automatically disperse iota tokens which are sent to the contract to a group +// of member accounts according to predefined division factors. The intent is +// to showcase basic functionality of WasmLib through a minimal implementation +// and not to come up with a complete robust real-world solution. +// Note that we have drawn sometimes out constructs that could have been done +// in a single line over multiple statements to be able to properly document +// step by step what is happening in the code. We also unnecessarily annotate +// all 'let' statements with their assignment type to improve understanding. + +import * as wasmlib from 'wasmlib'; +import * as sc from './index'; + +// 'init' is used as a way to initialize a smart contract. It is an optional +// function that will automatically be called upon contract deployment. In this +// case we use it to initialize the 'owner' state variable so that we can later +// use this information to prevent non-owners from calling certain functions. +// The 'init' function takes a single optional parameter: +// - 'owner', which is the agent id of the entity owning the contract. +// When this parameter is omitted the owner will default to the contract creator. +export function funcInit(ctx: wasmlib.ScFuncContext, f: sc.InitContext): void { + // The schema tool has already created a proper InitContext for this function that + // allows us to access call parameters and state storage in a type-safe manner. + + // First we set up a default value for the owner in case the optional 'owner' + // parameter was omitted. We use the agent that sent the deploy request. + let owner: wasmlib.ScAgentID = ctx.requestSender(); + + // Now we check if the optional 'owner' parameter is present in the params map. + if (f.params.owner().exists()) { + // Yes, it was present, so now we overwrite the default owner with + // the one specified by the 'owner' parameter. + owner = f.params.owner().value(); + } + + // Now that we have sorted out which agent will be the owner of this contract + // we will save this value in the 'owner' variable in state storage on the host. + // Read the documentation on schema.yaml to understand why this state variable is + // supported at compile-time by code generated from schema.yaml by the schema tool. + f.state.owner().setValue(owner); +} +``` + + + + +We define an owner variable and allow it to be something other than the default value of +the contract creator. It is always a good idea to be flexible enough to transfer +ownership to another entity if necessary. Remember that once a smart contract has been +deployed it is no longer possible to change it. Therefore, it is good practice to think +through situations that could require a change in advance and allow the contract itself to +handle such changes through its state by providing a proper function interface: + + + + + +```go +// 'setOwner' is used to change the owner of the smart contract. +// It updates the 'owner' state variable with the provided agent id. +// The 'setOwner' function takes a single mandatory parameter: +// - 'owner', which is the agent id of the entity that will own the contract. +// Only the current owner can change the owner. +func funcSetOwner(_ wasmlib.ScFuncContext, f *SetOwnerContext) { + // Note that the schema tool has already dealt with making sure that this function + // can only be called by the owner and that the required parameter is present. + // So once we get to this point in the code we can take that as a given. + + // Save the new owner parameter value in the 'owner' variable in state storage. + f.State.Owner().SetValue(f.Params.Owner().Value()) +} +``` + + + + +```rust +// 'setOwner' is used to change the owner of the smart contract. +// It updates the 'owner' state variable with the provided agent id. +// The 'setOwner' function takes a single mandatory parameter: +// - 'owner', which is the agent id of the entity that will own the contract. +// Only the current owner can change the owner. +pub fn func_set_owner(_ctx: &ScFuncContext, f: &SetOwnerContext) { + // Note that the schema tool has already dealt with making sure that this function + // can only be called by the owner and that the required parameter is present. + // So once we get to this point in the code we can take that as a given. + + // Save the new owner parameter value in the 'owner' variable in state storage. + f.state.owner().set_value(&f.params.owner().value()); +} +``` + + + + +```ts +// 'setOwner' is used to change the owner of the smart contract. +// It updates the 'owner' state variable with the provided agent id. +// The 'setOwner' function takes a single mandatory parameter: +// - 'owner', which is the agent id of the entity that will own the contract. +// Only the current owner can change the owner. +export function funcSetOwner( + ctx: wasmlib.ScFuncContext, + f: sc.SetOwnerContext, +): void { + // Note that the schema tool has already dealt with making sure that this function + // can only be called by the owner and that the required parameter is present. + // So once we get to this point in the code we can take that as a given. + + // Save the new owner parameter value in the 'owner' variable in state storage. + f.state.owner().setValue(f.params.owner().value()); +} +``` + + + + +Note that we only define a single owner here. +A proper fall-back could require multiple owners in case the owner entity could disappear, +which would allow others to take over instead of the contract becoming immutable about the “owner functionality”. +We cannot stress enough how important it is to **think through every aspect of a smart contract before deployment**. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/params.mdx b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/params.mdx new file mode 100644 index 00000000000..60691771f75 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/params.mdx @@ -0,0 +1,102 @@ +--- +description: "Learn how to define function parameters using the 'params' subsection, and how the Schema Tool facilitates this process." +tags: + - Function Parameters + - Schema Tool + - Params Subsection + - Optional Parameters + - Parameter Proxy +image: /img/logo/WASP_logo_dark.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Define Function Parameters + +You can use the optional [`params`](params.mdx) subsection to specify the parameters a function accepts. +This section can define both mandatory and optional parameters. +Optional parameters are denoted with a question mark `?` following the field type. + +## Schema Tool Automation + +The [Schema Tool](usage.mdx) streamlines the creation of functions by: + +- Generating an immutable structure holding parameter proxies from the [Params](params.mdx) map. +- Checking the presence and data type of non-optional parameters before the function call. + +These functionalities allow users to directly use parameter proxies in the structure passed to the function. + +:::note + +Omitting the `params` subsection results in no structure generation or parameter passing to the function. + +::: + +For example, here is the structure generated for the immutable [Params](params.mdx) for +the `member` function: + + + + + +```go +type ImmutableMemberParams struct { + proxy wasmtypes.Proxy +} + +// address of dividend recipient +func (s ImmutableMemberParams) Address() wasmtypes.ScImmutableAddress { + return wasmtypes.NewScImmutableAddress(s.proxy.Root(ParamAddress)) +} + +// relative division factor +func (s ImmutableMemberParams) Factor() wasmtypes.ScImmutableUint64 { + return wasmtypes.NewScImmutableUint64(s.proxy.Root(ParamFactor)) +} +``` + + + + +```rust +#[derive(Clone)] +pub struct ImmutableMemberParams { + pub(crate) proxy: Proxy, +} + +impl ImmutableMemberParams { + // address of dividend recipient + pub fn address(&self) -> ScImmutableAddress { + ScImmutableAddress::new(self.proxy.root(PARAM_ADDRESS)) + } + + // relative division factor + pub fn factor(&self) -> ScImmutableUint64 { + ScImmutableUint64::new(self.proxy.root(PARAM_FACTOR)) + } +} +``` + + + + +```ts +export class ImmutableMemberParams extends wasmtypes.ScProxy { + // address of dividend recipient + address(): wasmtypes.ScImmutableAddress { + return new wasmtypes.ScImmutableAddress(this.proxy.root(sc.ParamAddress)); + } + + // relative division factor + factor(): wasmtypes.ScImmutableUint64 { + return new wasmtypes.ScImmutableUint64(this.proxy.root(sc.ParamFactor)); + } +} +``` + + + + +The [Schema Tool](usage.mdx) will also generate a mutable version of the structure, +suitable for providing the parameters when calling this smart contract function from any [Call Context](../../explanations/context.mdx). diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/post.mdx b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/post.mdx new file mode 100644 index 00000000000..e4ef8b23b4d --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/post.mdx @@ -0,0 +1,99 @@ +--- +tags: + - function descriptor + - return values + - request + - post + - smart contract chain + - Asynchronous function +description: Asynchronous function calls between smart contracts are posted as requests on the Tangle. They allow you to invoke any smart contract function that is not a View on any smart contract chain. +image: /img/logo/WASP_logo_dark.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Post Asynchronous Requests + +Asynchronous requests enable interactions between different contracts. +Learn how to navigate the subtleties of posting asynchronous requests on the Tangle, +and how to effectively manage tokens and delays in execution. + +## Overview of Asynchronous Function Calls + +### Posting Requests on the Tangle + +Asynchronous function calls occur through requests posted on the Tangle. +These calls can invoke any function that is not a [View](views.mdx) on any smart contract chain. + +### Function Descriptor Methods + +To post a request, use the following methods from the function descriptor: + +- `post()`: Posts to the current chain. +- `postToChain()`: Allows specifying the chain through the chain ID parameter. + +### Delayed Execution + +You can set a delay in the execution using the `delay()` method, +enhancing smart contracts with timed actions or time-lock functionalities. + + + + + +```go +eor := ScFuncs.EndOfRound(ctx) +eor.Func.Delay(3600).Post() +``` + + + + +```rust +let eor = ScFuncs::end_of_round(ctx); +eor.func.delay(3600).post(); +``` + + + + +```ts +let eor = sc.ScFuncs.endOfRound(ctx); +eor.func.delay(3600).post(); +``` + + + + +## Managing Tokens in Asynchronous Calls + +### Mandatory Token Transfer + +Asynchronous requests require a minimum token transfer to cover the gas for function call execution. +Unused tokens return to the caller's account on the chain. + +### Specifying Tokens + +You can specify tokens: + +- Explicitly, as in to synchronous calls. +- Automatically, letting WasmLib determine the minimum requisite amount. + +### Prohibited `delay()` with [`call()`](call.mdx) + +Using `delay()` before a [`call()`](call.mdx) will cause a panic due to indeterminate user intentions at compile-time +without substantial overhead. + +## Handling Return Values + +If you need some return values, +you will have to create a mechanism that can do so. +For example, +you can provide a callback chain/contract/function combination as part of the input parameters of the requested function so that upon completion, +that function can asynchronously post the results to the indicated function. +It will require a certain degree of cooperation between both smart contracts. + +### Future Prospects + +Future developments aim to facilitate a generic mechanism for seamless return value communication in asynchronous function calls. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/results.mdx b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/results.mdx new file mode 100644 index 00000000000..d80691a6888 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/results.mdx @@ -0,0 +1,85 @@ +--- +image: /img/logo/WASP_logo_dark.png +description: "Understand how to outline function results using the 'results' subsection and how the Schema Tool aids in this process." +tags: + - Function Results + - Schema Tool + - Results Subsection + - Mutable Structure + - Result Variables +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Define Function Results + +You can use the optional `results` subsection to detail the results a function can produce. +This setup aligns with the field definitions seen in the [Params](params.mdx) subsection. + +## Schema Tool Features + +The [Schema Tool](usage.mdx) assists in this setup by: + +- Creating a mutable structure that includes proxies for each result variable found in the [Results](results.mdx) map. +- Enabling users to assign values to result variables via this generated structure during the function call. + +:::note + +If the `results` subsection is not used, no structure will be created or conveyed to the function. + +::: + +For example, here is the structure generated for the mutable results for the `getFactor` +function: + + + + + +```go +type MutableGetFactorResults struct { + proxy wasmtypes.Proxy +} + +// relative division factor +func (s MutableGetFactorResults) Factor() wasmtypes.ScMutableUint64 { + return wasmtypes.NewScMutableUint64(s.proxy.Root(ResultFactor)) +} +``` + + + + +```rust +#[derive(Clone)] +pub struct MutableGetFactorResults { + pub(crate) proxy: Proxy, +} + +impl MutableGetFactorResults { + // relative division factor + pub fn factor(&self) -> ScMutableUint64 { + ScMutableUint64::new(self.proxy.root(RESULT_FACTOR)) + } +} +``` + + + + +```ts +export class MutableGetFactorResults extends wasmtypes.ScProxy { + // relative division factor + factor(): wasmtypes.ScMutableUint64 { + return new wasmtypes.ScMutableUint64(this.proxy.root(sc.ResultFactor)); + } +} +``` + + + + +Note that the [Schema Tool](usage.mdx) will also generate an immutable version of the +structure, suitable for accessing the results after by the caller of this smart contract +function. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/spec.mdx b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/spec.mdx new file mode 100644 index 00000000000..1c8c35fee58 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/spec.mdx @@ -0,0 +1,460 @@ +--- +tags: + - spec + - meta-programming + - compile +description: The spec of schema tool and how to develop schema tool. +image: /img/logo/WASP_logo_dark.png +--- + +# Spec + +## Workflow + +1. YAML file would be converted to a tree of `wasp_yaml.Node` +2. Convert the tree to a `model.SchemaDef` object +3. Compile the `model.SchemaDef` object to `model.Schema` object by calling `Compile()` +4. Convert `model.Schema` object to the Smart Contract of targeting languages + +## Types + +### model.SchemaDef + +`model.SchemaDef` is a intermediate object during the Smart Contract generation. An YAML file will be converted to `model.SchemaDef` object. +During the conversion, each YAML attribute except the top-level ones (`name`, `description`, `events`, `structs`, `typedefs`, `state`, `funcs`, `views`) will be converted into `DefElt`. + +Therefore, for YAML tags `name`, `description`, the values of them will be converted into 2 independent `DefElt`. + +``` +name: TestName +description: This is test description +``` + +For keywords that can have multiple values can be seen as either a one layer map (i.e., `typedefs` and `state`) +or two layer map (i.e., `typedefs` and `state`). A one layer map will be converted into `DefMap` which +is a map whose key and value are both `DefElt`. And a two layer map will be converted into `DefMapMap` which +is a map whose key is `DefElt` and value is `DefMap`. + +The definition of `DefElt` is shown as following, + +```go +type DefElt struct { + Val string + Comment string + Line int +} +``` + +It contains the raw value of the YAML attributes (without extracting the information), the comment belongs to the +YAML attribute, and the line number of the YAML attribute. + +Here is an example of one layer map + +```yaml +typedefs: + TestTypedef1: String + TestTypedef2: String +state: + TestState1: Int64[] + TestState2: Int64[] +``` + +And an example of two layer map + +```yaml +structs: + point: + x: Int32 + y: Int32 +funcs: + testFunc: + params: + testFuncParam: Uint64 + results: + testFuncResult: Uint64 +views: + testView: + params: + testViewParam: Uint64 + results: + testViewResult: Uint64 +``` + +Next, schema tool will set each fields in `SchemaDef` variable. + +```go +type SchemaDef struct { + Copyright string + Name DefElt + Description DefElt + Events DefMapMap + Structs DefMapMap + Typedefs DefMap + State DefMap + Funcs FuncDefMap + Views FuncDefMap +} +``` + +### model.Schema + +By calling `Schema.Compile()`, `model.SchemaDef` object will be compiled into `model.Schema`. +During the compilation, schema tool will extract the rules from the YAML attributes. + +Here is the definition of a `Schema` object. + +```go +type Schema struct { + ContractName string + Copyright string + PackageName string + Description string + CoreContracts bool + SchemaTime time.Time + Events []*Struct + Funcs []*Func + Params []*Field + Results []*Field + StateVars []*Field + Structs []*Struct + Typedefs []*Field +} +``` + +And let's take a close look at `Field` object. + +```go +type Field struct { + Name string // external name for this field + Alias string // internal name alias, can be different from Name + Array bool + FldComment string + MapKey string + Optional bool + Type string + BaseType bool + Comment string + Line int // the line number originally in yaml/json file +} +``` + +As you can see `typedefs` was a simple `DefMap`, which consists a map whose key and value are both `DefElt`, +and `DefElt` a simple object contains only raw string of the YAML attribute, comment and line number. +However, after the compilation, information is extracted from the raw string, so do some checks are conducted in this step. + +### Compile + +An emitter is used for filling corresponding values into templates under `tools/schema/generator`. +For how to do meta-programming with emitter, see section [Emitter](#emitter) + +```go +type ( + FieldMap map[string]*Field + FieldMapMap map[string]FieldMap + StringMap map[string]string + StringMapMap map[string]StringMap +) +``` + +## Comments + +### Header Comment and Line Comment + +Header comment has higher priority than the line comment. If there are both header comment and line comment presented at +same YAML attribute, then schema tool will keep only the header comment. + +### Comment Block + +A comment block is a chunk of comment that doesn't have a line break to separate it. Schema tool would take the +header comment that immediately followed by the YAML attribute or the line comment block if header comment block is not +presented. + +Therefore, for the following case + +```yaml +typedefs: + # header comment 1 + # header comment 2 + + # header comment 3 + # header comment 4 + TestTypedef: + String # line comment 1 + # line comment 2 +``` + +only these 2 lines + +```yaml +# header comment 3 +# header comment 4 +``` + +will be kept and presented in the final Smart Contract. + +And the next case + +```yaml +typedefs: + TestTypedef: + String # line comment 1 + # line comment 2 + + # line comment 3 + # line comment 4 +``` + +only these 2 lines + +```yaml +# line comment 1 +# line comment 2 +``` + +will be kept and presented in the final Smart Contract. + +## Emitter + +### Access Keys + +With `$` prepending a key (keys are set in `GenBase.setCommonKeys()`, `GenBase.setFieldKeys()`, `GenBase.setFuncKeys()`), schema tool can access the value of the key in `GenBase.keys` according to the current context. For example, if you want to access lower case package name, you can access it with `$package`. +To dynamically add a new key in templates (under gotemplates, rstemplates, and tstemplates), you can call `$#set` instruction, see section [set](#set) for more information. + +### Key And Plain String Concatenation + +To concatenate a value from accessing key and a plain string, you should use `$+` operator. +For example, here `FuncName` is a key that preserves the name of the function under current context, and we want to concatenate the function name with "Mutable" and "Results". +In other words, we want to do the same task as the following python code and get the result in `result` variable. + +```python +func_name = "..." # function name under current context +result = "Mutable" + func_name + "Results" # concatenate the strings into the result +``` + +In the schema template language, we should call `Mutable$FuncName$+Results`. + +### Instructions + +Keywords follows `$#` are the instructions defined in our schema template language. One thing you should aware, now, all the instruction should be presented at the beginning of each line. In other words, no spaces and characters are allowed to exist ahead of an instruction. +Here is the list of all the instruction keywords. + +- emit +- each +- func +- if +- set + +We are going to introduce how to use each instruction as follows. Or you can check the implementation of `GenBase.emit()` to know how are they implemented in detailed. + +#### emit + +`emit` is using for expanding templates. The syntax of `emit` instruction is + +``` +$#emit template +``` + +Here, `template` is any template which defined under gotemplates,rstemplates). +Templates are defined in `model.StringMap`. In the instruction call of `emit` just simply use the name of the template (the key in `model.StringMap`). +If you want to insert the `copyright` template to a assigned location, then you should call + +``` +$#emit copyright +``` + +#### each + +`each` processes the template for each item in the array. The syntax of `each` instruction is + +``` +$#each array template +``` + +Here `array` is either a predefined keyword (we are going to introduce each of them as follow) or a multi-lines string. +If a multi-lines string is presented, then the multi-lines string will be expanded and append newline escape character of targeting languages in the end of each line. + +##### event + +Iterate the fields in a event. + +##### events + +Iterate all the `events` in the contract. + +##### func + +Iterate all the `funcs` in the contract. + +##### mandatory + +Iterate all the mandatory fields in the current processed function. The mandatory field must be basetype and not an array or a map. + +##### param + +Iterate all the `params` fields in the current processed function. + +##### params + +Iterate all the `params` fields in the current contract. + +##### result + +Iterate all the `results` fields in the current processed function. + +##### results + +Iterate all the `results` fields in the current contract. + +##### state + +Iterate all the `state` in the contract. + +##### struct + +Iterate the fields in a struct. + +##### structs + +Iterate all the `structs` in the contract. + +##### typedef + +Iterate all the typedefs in the contract. + +#### func + +Currently not used. + +#### if + +The syntax of `if` is + +``` +$#if condition template [elseTemplate] +``` + +`if` processes template when the named condition is true, and it processes the optional `elseTemplate` when the named condition is false + +`condition` is either the predefined conditions (explained as following) or a key that may exist in `keys`. +If a key is presented, then `if` instruction would be used for check whether this key exists in `keys` or not. If the key exists, then `if` will return true, otherwise it will return false. + +And here are the predefined conditions. + +##### array + +Is the current processed field an array? + +##### basetype + +Is the current processed field in basetype? `basetype`s are defined in the map `FieldTypes` in `tools/schema/model/field.go`. + +##### core + +Is the current processed contract a core contract? + +##### event + +Does the current processed event have any field? + +##### events + +Is there any event in the current processed contract? + +##### exist + +Does the value of key `proxy` exist? + +##### func + +Is the current processed function a `func` or a `view`? Return true if it is a `func`. + +##### funcs + +Is there any function in the current processed contract? + +##### init + +Is the current function an init function? An init function will automatically be called immediately after the first time the contract has been deployed to the VM. + +##### mandatory + +Is current field a mandatory field? + +##### map + +Is current processed field a map (check if the `currentField.MapKey` is empty)? + +##### mut + +Is the value in key `mut` Mutable? + +##### param + +Does the current processed function have any parameter? + +##### params + +Does the current contract have any `params` field? + +##### ptrs + +Does the current processed function have either `params` or `results`. +This is used for implementing function object in Rust and TypeScript. + +##### result + +Does the current processed function have any return value? + +##### results + +Does the current contract have any `results` field? + +##### state + +Does the current contract have any `state` field? + +##### structs + +Does the current contract have any `structs` field? + +##### this + +Is the alias name of the current processed field `this`? + +##### typedef + +Is the current processed field a `typedef`? + +##### typedefs + +Does the current contract have any `typedefs` field? + +##### view + +Is the current processed function a `view` or a `func`? Return true if it is a `view`. + +##### else + +If you want to process a template under negate condition, then you can call + +``` +$#if condition else elseTemplate +``` + +Here `else` is a predefined empty template, which is defined at[`tools/schema/generator/templates.go`. + +#### set + +`set` is used for To dynamically specify a value to a certain key. The syntax is + +``` +$#set key value +``` + +For example, if you want to dynamically add a new key `initFunc` with the value in key `nil` you can call + +``` +$#set initFunc $nil +``` + +A special key `exist` is used to add a newly generated type. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/state.mdx b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/state.mdx new file mode 100644 index 00000000000..70252bfb4a1 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/state.mdx @@ -0,0 +1,187 @@ +--- +tags: + - state + - access + - storage + - key + - data + - value + +description: The smart contract state storage on the host consists of a single key/value map, as long as you access the data in the same way that you used to store it, you will always get valid data back. + +image: /img/logo/WASP_logo_dark.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Define the State + +In smart contract state storage, there is only a single key/value map, +where both the key and value are constituted of raw data bytes. +To ensure the retrieval of valid data, access it in the manner it was stored. + +The [Schema Tool](usage.mdx) facilitates this by generating a type-safe layer +that oversees the consistent utilization of the expected data type during _data storage_ and retrieval. + +## State Section in Schema Definition File + +In the schema definition file the `state` section hosts field definitions, +delineating the variables stored in the state storage. +Each field is defined with a YAML key/value pair, indicating its name and data type. +This pair can optionally be followed by a descriptive comment. + +With these details, the [Schema Tool](usage.mdx) creates specific code to type-safely access state variables. +Take a closer look at the `state` section in the `dividend` example to understand this better: + + + + +```yaml +state: + memberList: Address[] # array with all the recipients of this dividend + + # factors per member + + members: map[Address]Uint64 # map with all the recipient factors of this dividend + owner: AgentID # owner of contract, the only one who can call 'member' func + totalFactor: Uint64 # sum of all recipient factors +``` + + + + +### Simple Variables + +Starting with straightforward state variables, `totalFactor`, +and `owner` are characterized as Uint64 and AgentID, respectively. +These represent predefined [WasmLib value types](../../reference/wasm-lib-data-types.mdx). + +### Arrays and Maps + +Next, the `memberList` variable denoted by empty brackets `[]`, symbolizing an array. +This array accommodates elements of a homogenous predefined Address value type. + +Lastly, the `members` variable, signified as a map with `map[]`, houses keys of a uniform predefined Address type. +Following the brackets, the homogenous value type, here `Uint64`, is mentioned. + + + + + +```go +type MutableDividendState struct { + proxy wasmtypes.Proxy +} + +func (s MutableDividendState) AsImmutable() ImmutableDividendState { + return ImmutableDividendState(s) +} + +// array with all the recipients of this dividend +func (s MutableDividendState) MemberList() ArrayOfMutableAddress { + return ArrayOfMutableAddress{proxy: s.proxy.Root(StateMemberList)} +} + +// map with all the recipient factors of this dividend +func (s MutableDividendState) Members() MapAddressToMutableUint64 { + return MapAddressToMutableUint64{proxy: s.proxy.Root(StateMembers)} +} + +// owner of contract, the only one who can call 'member' func +func (s MutableDividendState) Owner() wasmtypes.ScMutableAgentID { + return wasmtypes.NewScMutableAgentID(s.proxy.Root(StateOwner)) +} + +// sum of all recipient factors +func (s MutableDividendState) TotalFactor() wasmtypes.ScMutableUint64 { + return wasmtypes.NewScMutableUint64(s.proxy.Root(StateTotalFactor)) +} +``` + + + + +```rust +#[derive(Clone)] +pub struct MutableDividendState { + pub(crate) proxy: Proxy, +} + +impl MutableDividendState { + pub fn as_immutable(&self) -> ImmutableDividendState { + ImmutableDividendState { proxy: self.proxy.root("") } + } + + // array with all the recipients of this dividend + pub fn member_list(&self) -> ArrayOfMutableAddress { + ArrayOfMutableAddress { proxy: self.proxy.root(STATE_MEMBER_LIST) } + } + + // map with all the recipient factors of this dividend + pub fn members(&self) -> MapAddressToMutableUint64 { + MapAddressToMutableUint64 { proxy: self.proxy.root(STATE_MEMBERS) } + } + + // owner of contract, the only one who can call 'member' func + pub fn owner(&self) -> ScMutableAgentID { + ScMutableAgentID::new(self.proxy.root(STATE_OWNER)) + } + + // sum of all recipient factors + pub fn total_factor(&self) -> ScMutableUint64 { + ScMutableUint64::new(self.proxy.root(STATE_TOTAL_FACTOR)) + } +} +``` + + + + +```ts +export class MutableDividendState extends wasmtypes.ScProxy { + asImmutable(): sc.ImmutableDividendState { + return new sc.ImmutableDividendState(this.proxy); + } + + // array with all the recipients of this dividend + memberList(): sc.ArrayOfMutableAddress { + return new sc.ArrayOfMutableAddress(this.proxy.root(sc.StateMemberList)); + } + + // map with all the recipient factors of this dividend + members(): sc.MapAddressToMutableUint64 { + return new sc.MapAddressToMutableUint64(this.proxy.root(sc.StateMembers)); + } + + // owner of contract, the only one who can call 'member' func + owner(): wasmtypes.ScMutableAgentID { + return new wasmtypes.ScMutableAgentID(this.proxy.root(sc.StateOwner)); + } + + // sum of all recipient factors + totalFactor(): wasmtypes.ScMutableUint64 { + return new wasmtypes.ScMutableUint64(this.proxy.root(sc.StateTotalFactor)); + } +} +``` + + + + +## Generated Code Overview + +Examining the `state.xx`code, generated by the [Schema Tool](usage.mdx), +you can find the `MutableDividendState` struct. +This interface allows type-safe access to each state variable through mutable [proxies](../../schema/proxies.mdx), +establishing a one-to-one relationship with the `state` section in the schema definition file. + +### Proxy Interfaces + +Note the generated proxy interface named `MutableDividendState` for mutable `dividend` state. +It enables type-safe proxy object access for each corresponding variable. +Moreover, the tool auto-generates intermediate map and array proxy types, +such as `ArrayOfMutableAddress` and `MapAddressToMutableUint64`, +enforcing the utilization of respective homogenous types. + +See the full `state.xx` for more details. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/structs.mdx b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/structs.mdx new file mode 100644 index 00000000000..810c2f398b2 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/structs.mdx @@ -0,0 +1,513 @@ +--- +tags: + - functions + - state + - structures + - storage + - named fields + +description: You can use structs directly as a type in state storage definitions and the schema tool will automatically generate the proxy code to access it properly. + +image: /img/logo/WASP_logo_dark.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Structured Data Types + +The [Schema Tool](usage.mdx) allows you to define your structured data types that are +composed of the predefined WasmLib value data types. The tool will generate a struct with +named fields according to the definition in the schema definition file and also will +generate code to serialize and deserialize the structure to a byte array so that it can +be saved as a single unit of data bytes, for example in state storage. + +You can use structs directly as a type in state storage definitions, and the +[Schema Tool](usage.mdx) will automatically generate the proxy code to access and +(de)serialize it properly. + +For example, let's say you are creating a `betting` smart contract. Then, you would want to +store information for each bet. The Bet structure could consist of the bet amount and +time, the number of the item that was bet on, and the agent ID of the one who placed the +bet. And you would keep track of all bets in state storage in an array of Bet structs. To +do so, you would insert the following into the schema definition file: + + + + +```yaml +structs: + Bet: + amount: Int64 # bet amount + better: AgentID # who placed this bet + number: Int32 # number of item we bet on + time: Int64 # timestamp of this bet +state: + bets: Bet[] # all bets that were made in this round +``` + + + + +The [Schema Tool](usage.mdx) will generate the following code in `structs.xx` for the Bet +struct: + + + + + +```go +package betting + +import "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/wasmtypes" + +type Bet struct { + // bet amount + Amount int64 + // who placed this bet + Better wasmtypes.ScAgentID + // number of item we bet on + Number int32 + // timestamp of this bet + Time int64 +} + +func NewBetFromBytes(buf []byte) *Bet { + dec := wasmtypes.NewWasmDecoder(buf) + data := &Bet{} + data.Amount = wasmtypes.Int64Decode(dec) + data.Better = wasmtypes.AgentIDDecode(dec) + data.Number = wasmtypes.Int32Decode(dec) + data.Time = wasmtypes.Int64Decode(dec) + dec.Close() + return data +} + +func (o *Bet) Bytes() []byte { + enc := wasmtypes.NewWasmEncoder() + wasmtypes.Int64Encode(enc, o.Amount) + wasmtypes.AgentIDEncode(enc, o.Better) + wasmtypes.Int32Encode(enc, o.Number) + wasmtypes.Int64Encode(enc, o.Time) + return enc.Buf() +} + +type ImmutableBet struct { + proxy wasmtypes.Proxy +} + +func (o ImmutableBet) Exists() bool { + return o.proxy.Exists() +} + +func (o ImmutableBet) Value() *Bet { + return NewBetFromBytes(o.proxy.Get()) +} + +type MutableBet struct { + proxy wasmtypes.Proxy +} + +func (o MutableBet) Delete() { + o.proxy.Delete() +} + +func (o MutableBet) Exists() bool { + return o.proxy.Exists() +} + +func (o MutableBet) SetValue(value *Bet) { + o.proxy.Set(value.Bytes()) +} + +func (o MutableBet) Value() *Bet { + return NewBetFromBytes(o.proxy.Get()) +} +``` + + + + +```rust +use wasmlib::*; + +#[derive(Clone)] +pub struct Bet { + // bet amount + pub amount : i64, + // who placed this bet + pub better : ScAgentID, + // number of item we bet on + pub number : i32, + // timestamp of this bet + pub time : i64, +} + +impl Bet { + pub fn from_bytes(bytes: &[u8]) -> Bet { + let mut dec = WasmDecoder::new(bytes); + Bet { + amount : int64_decode(&mut dec), + better : agent_id_decode(&mut dec), + number : int32_decode(&mut dec), + time : int64_decode(&mut dec), + } + } + + pub fn to_bytes(&self) -> Vec { + let mut enc = WasmEncoder::new(); + int64_encode(&mut enc, self.amount); + agent_id_encode(&mut enc, &self.better); + int32_encode(&mut enc, self.number); + int64_encode(&mut enc, self.time); + enc.buf() + } +} + +#[derive(Clone)] +pub struct ImmutableBet { + pub(crate) proxy: Proxy, +} + +impl ImmutableBet { + pub fn exists(&self) -> bool { + self.proxy.exists() + } + + pub fn value(&self) -> Bet { + Bet::from_bytes(&self.proxy.get()) + } +} + +#[derive(Clone)] +pub struct MutableBet { + pub(crate) proxy: Proxy, +} + +impl MutableBet { + pub fn delete(&self) { + self.proxy.delete(); + } + + pub fn exists(&self) -> bool { + self.proxy.exists() + } + + pub fn set_value(&self, value: &Bet) { + self.proxy.set(&value.to_bytes()); + } + + pub fn value(&self) -> Bet { + Bet::from_bytes(&self.proxy.get()) + } +} +``` + + + + +```ts +import * as wasmtypes from 'wasmlib/wasmtypes'; + +export class Bet { + // bet amount + amount: i64 = 0; + // who placed this bet + better: wasmtypes.ScAgentID = wasmtypes.agentIDFromBytes([]); + // number of item we bet on + number: i32 = 0; + // timestamp of this bet + time: i64 = 0; + + static fromBytes(buf: u8[]): Bet { + const dec = new wasmtypes.WasmDecoder(buf); + const data = new Bet(); + data.amount = wasmtypes.int64Decode(dec); + data.better = wasmtypes.agentIDDecode(dec); + data.number = wasmtypes.int32Decode(dec); + data.time = wasmtypes.int64Decode(dec); + dec.close(); + return data; + } + + bytes(): u8[] { + const enc = new wasmtypes.WasmEncoder(); + wasmtypes.int64Encode(enc, this.amount); + wasmtypes.agentIDEncode(enc, this.better); + wasmtypes.int32Encode(enc, this.number); + wasmtypes.int64Encode(enc, this.time); + return enc.buf(); + } +} + +export class ImmutableBet extends wasmtypes.ScProxy { + exists(): bool { + return this.proxy.exists(); + } + + value(): Bet { + return Bet.fromBytes(this.proxy.get()); + } +} + +export class MutableBet extends wasmtypes.ScProxy { + delete(): void { + this.proxy.delete(); + } + + exists(): bool { + return this.proxy.exists(); + } + + setValue(value: Bet): void { + this.proxy.set(value.bytes()); + } + + value(): Bet { + return Bet.fromBytes(this.proxy.get()); + } +} +``` + + + + +Notice how the generated ImmutableBet and MutableBet proxies use the fromBytes() and +toBytes() (de)serialization code to automatically transform byte arrays into Bet structs. + +The generated code in `state.xx` that implements the state interface is shown here: + + + + + +```go +package betting + +import "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/wasmtypes" + +type ArrayOfImmutableBet struct { + proxy wasmtypes.Proxy +} + +func (a ArrayOfImmutableBet) Length() uint32 { + return a.proxy.Length() +} + +func (a ArrayOfImmutableBet) GetBet(index uint32) ImmutableBet { + return ImmutableBet{proxy: a.proxy.Index(index)} +} + +type ImmutableBettingState struct { + proxy wasmtypes.Proxy +} + +// all bets that were made in this round +func (s ImmutableBettingState) Bets() ArrayOfImmutableBet { + return ArrayOfImmutableBet{proxy: s.proxy.Root(StateBets)} +} + +// current owner of this smart contract +func (s ImmutableBettingState) Owner() wasmtypes.ScImmutableAgentID { + return wasmtypes.NewScImmutableAgentID(s.proxy.Root(StateOwner)) +} + +type ArrayOfMutableBet struct { + proxy wasmtypes.Proxy +} + +func (a ArrayOfMutableBet) AppendBet() MutableBet { + return MutableBet{proxy: a.proxy.Append()} +} + +func (a ArrayOfMutableBet) Clear() { + a.proxy.ClearArray() +} + +func (a ArrayOfMutableBet) Length() uint32 { + return a.proxy.Length() +} + +func (a ArrayOfMutableBet) GetBet(index uint32) MutableBet { + return MutableBet{proxy: a.proxy.Index(index)} +} + +type MutableBettingState struct { + proxy wasmtypes.Proxy +} + +func (s MutableBettingState) AsImmutable() ImmutableBettingState { + return ImmutableBettingState(s) +} + +// all bets that were made in this round +func (s MutableBettingState) Bets() ArrayOfMutableBet { + return ArrayOfMutableBet{proxy: s.proxy.Root(StateBets)} +} + +// current owner of this smart contract +func (s MutableBettingState) Owner() wasmtypes.ScMutableAgentID { + return wasmtypes.NewScMutableAgentID(s.proxy.Root(StateOwner)) +} +``` + + + + +```rust +use wasmlib::*; + +use crate::*; + +#[derive(Clone)] +pub struct ArrayOfImmutableBet { + pub(crate) proxy: Proxy, +} + +impl ArrayOfImmutableBet { + pub fn length(&self) -> u32 { + self.proxy.length() + } + + + pub fn get_bet(&self, index: u32) -> ImmutableBet { + ImmutableBet { proxy: self.proxy.index(index) } + } +} + +#[derive(Clone)] +pub struct ImmutableBettingState { + pub(crate) proxy: Proxy, +} + +impl ImmutableBettingState { + // all bets that were made in this round + pub fn bets(&self) -> ArrayOfImmutableBet { + ArrayOfImmutableBet { proxy: self.proxy.root(STATE_BETS) } + } + + // current owner of this smart contract + pub fn owner(&self) -> ScImmutableAgentID { + ScImmutableAgentID::new(self.proxy.root(STATE_OWNER)) + } +} + +#[derive(Clone)] +pub struct ArrayOfMutableBet { + pub(crate) proxy: Proxy, +} + +impl ArrayOfMutableBet { + + pub fn append_bet(&self) -> MutableBet { + MutableBet { proxy: self.proxy.append() } + } + pub fn clear(&self) { + self.proxy.clear_array(); + } + + pub fn length(&self) -> u32 { + self.proxy.length() + } + + + pub fn get_bet(&self, index: u32) -> MutableBet { + MutableBet { proxy: self.proxy.index(index) } + } +} + +#[derive(Clone)] +pub struct MutableBettingState { + pub(crate) proxy: Proxy, +} + +impl MutableBettingState { + pub fn as_immutable(&self) -> ImmutableBettingState { + ImmutableBettingState { proxy: self.proxy.root("") } + } + + // all bets that were made in this round + pub fn bets(&self) -> ArrayOfMutableBet { + ArrayOfMutableBet { proxy: self.proxy.root(STATE_BETS) } + } + + // current owner of this smart contract + pub fn owner(&self) -> ScMutableAgentID { + ScMutableAgentID::new(self.proxy.root(STATE_OWNER)) + } +} +``` + + + + +```ts +import * as wasmtypes from 'wasmlib/wasmtypes'; +import * as sc from './index'; + +export class ArrayOfImmutableBet extends wasmtypes.ScProxy { + length(): u32 { + return this.proxy.length(); + } + + getBet(index: u32): sc.ImmutableBet { + return new sc.ImmutableBet(this.proxy.index(index)); + } +} + +export class ImmutableBettingState extends wasmtypes.ScProxy { + // all bets that were made in this round + bets(): sc.ArrayOfImmutableBet { + return new sc.ArrayOfImmutableBet(this.proxy.root(sc.StateBets)); + } + + // current owner of this smart contract + owner(): wasmtypes.ScImmutableAgentID { + return new wasmtypes.ScImmutableAgentID(this.proxy.root(sc.StateOwner)); + } +} + +export class ArrayOfMutableBet extends wasmtypes.ScProxy { + appendBet(): sc.MutableBet { + return new sc.MutableBet(this.proxy.append()); + } + + clear(): void { + this.proxy.clearArray(); + } + + length(): u32 { + return this.proxy.length(); + } + + getBet(index: u32): sc.MutableBet { + return new sc.MutableBet(this.proxy.index(index)); + } +} + +export class MutableBettingState extends wasmtypes.ScProxy { + asImmutable(): sc.ImmutableBettingState { + return new sc.ImmutableBettingState(this.proxy); + } + + // all bets that were made in this round + bets(): sc.ArrayOfMutableBet { + return new sc.ArrayOfMutableBet(this.proxy.root(sc.StateBets)); + } + + // current owner of this smart contract + owner(): wasmtypes.ScMutableAgentID { + return new wasmtypes.ScMutableAgentID(this.proxy.root(sc.StateOwner)); + } +} +``` + + + + +The results are ImmutableBettingState and MutableBettingState structures that can +directly interface to the state of the betting contract. + +Note how the comments from the schema definition file have been copied to the code's structure definition and access +functions for the fields. This will allow your development environment to pop up context - sensitive help +for those fields and access functions. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/thunks.mdx b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/thunks.mdx new file mode 100644 index 00000000000..76531cd30a1 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/thunks.mdx @@ -0,0 +1,379 @@ +--- +description: 'Learn about thunk functions and how the Schema Tool uses them to facilitate smart contract function calls.' +tags: + - Thunk Functions + - Schema Tool + - Wrapper Function + - Smart Contract Functions + - Type-Safe + - Function Signature + - Code Injection +image: /img/logo/WASP_logo_dark.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Thunk Functions + +In software development, thunk functions are a crucial part of setting up smart contracts correctly, +facilitating type-safety and easy mapping of function names to their actual implementations. + +## Overview + +A thunk is a wrapper function employed to inject code before and/or after a function call. +It helps in adapting functions to meet changing demands. +Through the [Schema Tool](usage.mdx), +thunks are generated to establish correct calls to smart contract functions and to ensure type-safety. +They share a common function signature, fostering a straightforward creation of a function table for generic calls. + +## Role in Wasm + +Working hand in hand with the WebAssembly (Wasm) format, +thunks play a pivotal role in the `lib.xx` component. +Below is how a chunk of a `dividend` smart contract would look (the detailed thunk function content is omitted): + + + + + +```go +var exportMap = wasmlib.ScExportMap{ + Names: []string{ + FuncDivide, + FuncInit, + FuncMember, + FuncSetOwner, + ViewGetFactor, + ViewGetOwner, + }, + Funcs: []wasmlib.ScFuncContextFunction{ + funcDivideThunk, + funcInitThunk, + funcMemberThunk, + funcSetOwnerThunk, + }, + Views: []wasmlib.ScViewContextFunction{ + viewGetFactorThunk, + viewGetOwnerThunk, + }, +} + +func OnDispatch(index int32) { + exportMap.Dispatch(index) +} + +func funcDivideThunk(ctx wasmlib.ScFuncContext) {} +func funcInitThunk(ctx wasmlib.ScFuncContext) {} +func funcMemberThunk(ctx wasmlib.ScFuncContext) {} +func funcSetOwnerThunk(ctx wasmlib.ScFuncContext) {} +func viewGetFactorThunk(ctx wasmlib.ScViewContext) {} +func viewGetOwnerThunk(ctx wasmlib.ScViewContext) {} +``` + + + + +```rust +const EXPORT_MAP: ScExportMap = ScExportMap { + names: &[ + FUNC_DIVIDE, + FUNC_INIT, + FUNC_MEMBER, + FUNC_SET_OWNER, + VIEW_GET_FACTOR, + VIEW_GET_OWNER, + ], + funcs: &[ + func_divide_thunk, + func_init_thunk, + func_member_thunk, + func_set_owner_thunk, + ], + views: &[ + view_get_factor_thunk, + view_get_owner_thunk, + ], +}; + +pub fn on_dispatch(index: i32) { + EXPORT_MAP.dispatch(index); +} + +fn func_divide_thunk(ctx: &ScFuncContext) {} +fn func_init_thunk(ctx: &ScFuncContext) {} +fn func_member_thunk(ctx: &ScFuncContext) {} +fn func_set_owner_thunk(ctx: &ScFuncContext) {} +fn view_get_factor_thunk(ctx: &ScViewContext) {} +fn view_get_owner_thunk(ctx: &ScViewContext) {} +``` + + + + +```ts +const exportMap: wasmlib.ScExportMap = { + names: [ + sc.FuncDivide, + sc.FuncInit, + sc.FuncMember, + sc.FuncSetOwner, + sc.ViewGetFactor, + sc.ViewGetOwner, + ], + funcs: [funcDivideThunk, funcInitThunk, funcMemberThunk, funcSetOwnerThunk], + views: [viewGetFactorThunk, viewGetOwnerThunk], +}; + +export function on_dispatch(index: i32): void { + exportMap.dispatch(index); +} + +function funcDivideThunk(ctx: ScFuncContext) {} +function funcInitThunk(ctx: ScFuncContext) {} +function funcMemberThunk(ctx: ScFuncContext) {} +function funcSetOwnerThunk(ctx: ScFuncContext) {} +function viewGetFactorThunk(ctx: ScViewContext) {} +function viewGetOwnerThunk(ctx: ScViewContext) {} +``` + + + + +## The Dispatch Process + +The central player here is the `OnDispatch()` function, +called by the primary Wasm file, essentially a dynamic link library. +This mechanism keeps the smart contract (SC) code self-contained and versatile, +fitting for both Wasm requirements and direct client-side executions. + +To meet Wasm's demands, we implement `on_load()` and `on_call()` callbacks that collaborate with `OnDispatch()` in the `lib.xx`, +orchestrating a seamless dispatch process. + +### `on_load()` + +The `on_load()` Wasm function will be called by the Wasm VM host upon loading of the Wasm +code. It will inform the host of all the function ids and types (Func or View) that this +smart contract provides. + +### `on_call()` + +When the host needs to call a function of the smart contract it will call the `on_call()` +callback function with the corresponding function id, and then the `on_call()` function +will dispatch the call via the `ScExportMap` mapping table that was generated by the +[Schema Tool](usage.mdx) to the proper associated thunk function. + +## Generated Main Entry Point + +Here is the generated `main.xx` that forms the main entry point for the Wasm code: + + + + + +```go +//go:build wasm +// +build wasm + +package main + +import "github.com/iotaledger/wasp/packages/wasmvm/wasmvmhost/go/wasmvmhost" + +import "github.com/iotaledger/wasp/contracts/wasm/dividend/go/dividend" + +func main() { +} + +func init() { + wasmvmhost.ConnectWasmHost() +} + +//export on_call +func onCall(index int32) { + dividend.OnDispatch(index) +} + +//export on_load +func onLoad() { + dividend.OnDispatch(-1) +} +``` + + + + +```rust +use dividend::*; +use wasmvmhost::*; + +#[no_mangle] +fn on_call(index: i32) { + WasmVmHost::connect(); + on_dispatch(index); +} + +#[no_mangle] +fn on_load() { + WasmVmHost::connect(); + on_dispatch(-1); +} +``` + + + + +```ts +import * as wasmvmhost from 'wasmvmhost'; +import * as sc from './dividend'; + +export function on_call(index: i32): void { + wasmvmhost.WasmVMHost.connect(); + sc.onDispatch(index); +} + +export function on_load(): void { + wasmvmhost.WasmVMHost.connect(); + sc.onDispatch(-1); +} +``` + + + + +Finally, here is an example implementation of a thunk function for the `setOwner()` +contract function. You can examine the other thunk functions that all follow the same +pattern in the generated `lib.xx`: + + + + + +```go +type SetOwnerContext struct { + Params ImmutableSetOwnerParams + State MutableDividendState +} + +func funcSetOwnerThunk(ctx wasmlib.ScFuncContext) { + ctx.Log("dividend.funcSetOwner") + f := &SetOwnerContext{ + Params: ImmutableSetOwnerParams{ + proxy: wasmlib.NewParamsProxy(), + }, + State: MutableDividendState{ + proxy: wasmlib.NewStateProxy(), + }, + } + + // only defined owner of contract can change owner + access := f.State.Owner() + ctx.Require(access.Exists(), "access not set: owner") + ctx.Require(ctx.Caller() == access.Value(), "no permission") + + ctx.Require(f.Params.Owner().Exists(), "missing mandatory owner") + funcSetOwner(ctx, f) + ctx.Log("dividend.funcSetOwner ok") +} +``` + + + + +```rust +pub struct SetOwnerContext { + params: ImmutableSetOwnerParams, + state: MutableDividendState, +} + +fn func_set_owner_thunk(ctx: &ScFuncContext) { + ctx.log("dividend.funcSetOwner"); + let f = SetOwnerContext { + params: ImmutableSetOwnerParams { proxy: params_proxy() }, + state: MutableDividendState { proxy: state_proxy() }, + }; + + // only defined owner of contract can change owner + let access = f.state.owner(); + ctx.require(access.exists(), "access not set: owner"); + ctx.require(ctx.caller() == access.value(), "no permission"); + + ctx.require(f.params.owner().exists(), "missing mandatory owner"); + func_set_owner(ctx, &f); + ctx.log("dividend.funcSetOwner ok"); +} +``` + + + + +```ts +// this class is actually defined in contract.ts +export class SetOwnerContext { + params: sc.ImmutableSetOwnerParams = new sc.ImmutableSetOwnerParams( + wasmlib.paramsProxy(), + ); + state: sc.MutableDividendState = new sc.MutableDividendState( + wasmlib.ScState.proxy(), + ); +} + +function funcSetOwnerThunk(ctx: wasmlib.ScFuncContext): void { + ctx.log('dividend.funcSetOwner'); + let f = new sc.SetOwnerContext(); + + // only defined owner of contract can change owner + const access = f.state.owner(); + ctx.require(access.exists(), 'access not set: owner'); + ctx.require(ctx.caller().equals(access.value()), 'no permission'); + + ctx.require(f.params.owner().exists(), 'missing mandatory owner'); + sc.funcSetOwner(ctx, f); + ctx.log('dividend.funcSetOwner ok'); +} +``` + + + + +## The Thunk Function in Action + +### Log the Contract and Function Name + +First, the thunk logs the contract and function name to show that the call has started. + +### Set Up Strongly Typed Context + +Then it sets up a strongly typed function-specific context structure. First, we add the +function-specific immutable [Params](params.mdx) interface structure, which is only +present when the function can have parameters. Then we add the contract-specific +[State](state.mdx) interface structure. In this case, it is mutable because setOwner is a +[Func](funcs.mdx). For [Views](views.mdx), this would be an immutable state interface. +Finally, we would add the function-specific mutable [Results](results.mdx) interface +structure, which is only present when the function returns results. +This is not the case for this `setOwner()` function. + +### Set Up Access Control + +Next, it sets up access control for the function according to the schema definition file. +In this case, it retrieves the `owner` state variable through the function context, +requires that the variable exists, and then requires that the function's `caller()` +equals that value. Any failing requirement will panic out of the thunk function with an +error message. So, this code ensures that only the contract owner can call this +function. + +### Verify Function Parameters + +Now we get to the point where we can use the function-specific [Params](params.mdx) +interface to check for mandatory parameters. Each mandatory parameter is required to +exist, or else we will panic out of the thunk function with an error message. + +### Call the Smart Contract Function + +With the setup and automated checks completed, we now call the actual smart contract +function implementation the user maintains. +After this function has been completed, +we would process the returned results for those functions that have any (in this case, we +don't have results). +Finally, we log that the contract function has been completed +successfully. Remember that any error within the user function will cause a panic, so this +logging will never occur in case that happens. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/transfers.mdx b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/transfers.mdx new file mode 100644 index 00000000000..8e9e2447797 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/transfers.mdx @@ -0,0 +1,242 @@ +--- +description: 'Explore methods in the Call Context that facilitate the handling and transfer of asset balances in smart contracts using the `dividend` example.' +tags: + - Call Context + - Asset Balances + - ScBalances Proxy + - ScTransfer Proxy + - Dividend Smart Contract +image: /img/logo/WASP_logo_dark.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Transfer Tokens + +The [Call Context](../../explanations/context.mdx) in smart contracts introduces two vital methods - +`balances()` and `allowance()` - to manage token balances efficiently. +Understanding how to use these can be foundational in setting up smart contracts, +as demonstrated in the `dividend` smart contract example. + +## Methods Overview + +### 1. **`balances()` Method**: + +- **Functionality**: Fetch the present asset balances regulated by the smart contract. +- **Access**: Through the `ScBalances` proxy. + +### 2. **`allowance()` Method**: + +- **Functionality**: Verify the caller assets that the current smart contract function can use. +- **Transfer Requirement**: Assets are not automatically transferred; + the function must instigate the transfer explicitly within the allowed limit. +- **Access**: Through the `ScBalances` proxy. + +### 3. **`transfer_allowed()` Method**: + +- **Functionality**: Facilitate asset transfers from the caller's on-chain account to another on-chain account. +- **Proxy**: uses the `ScTransfer` proxy, a mutable variant of `ScBalances`. +- **Application**: In the `dividend` contract, it aids in distributing iotas to member accounts. + +## Dividend Smart Contract Example + +The `dividend` smart contract operates on a principle of equitable asset distribution to its members based on predefined factors. +Here's how it works: + +1. **Setup**: Establish a list of members with associated address/factor pairs and calculate the total factor sum. +2. **Function**: The `divide()` function manages the dividend distribution. +3. **Dividend Allocation**: + - **Input**: Iotas sent to the `divide()` function. + - **Distribution**: Proportional to the individual's factor. + - **Example**: For factors A:50, B:30, and C:20 (total 100): + - **A receives**: 50/100 of the input iotas. + - **B receives**: 30/100 of the input iotas. + - **C receives**: 20/100 of the input iotas. + +In this system, asset distribution is transparent, fair, and automated, ensuring a streamlined division process. + +Here is the `divide` function: + + + + + +```go +// 'divide' is a function that will take any iotas it receives and properly +// disperse them to the accounts in the member list according to the dispersion +// factors associated with these accounts. +// Anyone can send iotas to this function and they will automatically be +// divided over the member list. Note that this function does not deal with +// fractions. It simply truncates the calculated amount to the nearest lower +// integer and keeps any remaining tokens in the sender account. +func funcDivide(ctx wasmlib.ScFuncContext, f *DivideContext) { + // Create an ScBalances proxy to the allowance balances for this + // smart contract. + var allowance *wasmlib.ScBalances = ctx.Allowance() + + // Retrieve the amount of plain iota tokens from the account balance. + var amount uint64 = allowance.BaseTokens() + + // Retrieve the pre-calculated totalFactor value from the state storage. + var totalFactor uint64 = f.State.TotalFactor().Value() + + // Get the proxy to the 'members' map in the state storage. + var members MapAddressToMutableUint64 = f.State.Members() + + // Get the proxy to the 'memberList' array in the state storage. + var memberList ArrayOfMutableAddress = f.State.MemberList() + + // Determine the current length of the memberList array. + var size uint32 = memberList.Length() + + // Loop through all indexes of the memberList array. + for i := uint32(0); i < size; i++ { + // Retrieve the next indexed address from the memberList array. + var address wasmtypes.ScAddress = memberList.GetAddress(i).Value() + + // Retrieve the factor associated with the address from the members map. + var factor uint64 = members.GetUint64(address).Value() + + // Calculate the fair share of tokens to disperse to this member based on the + // factor we just retrieved. Note that the result will been truncated. + var share uint64 = amount * factor / totalFactor + + // Is there anything to disperse to this member? + if share > 0 { + // Yes, so let's set up an ScTransfer map proxy that transfers the + // calculated amount of tokens. + var transfer *wasmlib.ScTransfer = wasmlib.NewScTransferBaseTokens(share) + + // Perform the actual transfer of tokens from the caller allowance + // to the member account. + ctx.TransferAllowed(address.AsAgentID(), transfer) + } + } +} +``` + + + + +```rust +// 'divide' is a function that will take any iotas it receives and properly +// disperse them to the accounts in the member list according to the dispersion +// factors associated with these accounts. +// Anyone can send iotas to this function and they will automatically be +// divided over the member list. Note that this function does not deal with +// fractions. It simply truncates the calculated amount to the nearest lower +// integer and keeps any remaining tokens in its own account. They will be added +// to any next round of tokens received prior to calculation of the new +// dividend amounts. +pub fn func_divide(ctx: &ScFuncContext, f: &DivideContext) { + + // Create an ScBalances proxy to the allowance balances for this + // smart contract. + let allowance: ScBalances = ctx.allowance(); + + // Retrieve the amount of plain iota tokens from the account balance. + let amount: u64 = allowance.base_tokens(); + + // Retrieve the pre-calculated totalFactor value from the state storage. + let total_factor: u64 = f.state.total_factor().value(); + + // Get the proxy to the 'members' map in the state storage. + let members: MapAddressToMutableUint64 = f.state.members(); + + // Get the proxy to the 'memberList' array in the state storage. + let member_list: ArrayOfMutableAddress = f.state.member_list(); + + // Determine the current length of the memberList array. + let size: u32 = member_list.length(); + + // Loop through all indexes of the memberList array. + for i in 0..size { + // Retrieve the next indexed address from the memberList array. + let address: ScAddress = member_list.get_address(i).value(); + + // Retrieve the factor associated with the address from the members map. + let factor: u64 = members.get_uint64(&address).value(); + + // Calculate the fair share of tokens to disperse to this member based on the + // factor we just retrieved. Note that the result will be truncated. + let share: u64 = amount * factor / total_factor; + + // Is there anything to disperse to this member? + if share > 0 { + // Yes, so let's set up an ScTransfer map proxy that transfers the + // calculated amount of tokens. + let transfers: ScTransfer = ScTransfer::base_tokens(share); + + // Perform the actual transfer of tokens from the caller allowance + // to the member account. + ctx.transfer_allowed(&address.as_agent_id(), &transfers, true); + } + } +} +``` + + + + +```ts +// 'divide' is a function that will take any iotas it receives and properly +// disperse them to the accounts in the member list according to the dispersion +// factors associated with these accounts. +// Anyone can send iotas to this function and they will automatically be +// divided over the member list. Note that this function does not deal with +// fractions. It simply truncates the calculated amount to the nearest lower +// integer and keeps any remaining tokens in its own account. They will be added +// to any next round of tokens received prior to calculation of the new +// dividend amounts. +export function funcDivide( + ctx: wasmlib.ScFuncContext, + f: sc.DivideContext, +): void { + // Create an ScBalances proxy to the allowance balances for this + // smart contract. + let allowance: wasmlib.ScBalances = ctx.allowance(); + + // Retrieve the allowed amount of plain iota tokens from the account balance. + let amount: u64 = allowance.baseTokens(); + + // Retrieve the pre-calculated totalFactor value from the state storage. + let totalFactor: u64 = f.state.totalFactor().value(); + + // Get the proxy to the 'members' map in the state storage. + let members: sc.MapAddressToMutableUint64 = f.state.members(); + + // Get the proxy to the 'memberList' array in the state storage. + let memberList: sc.ArrayOfMutableAddress = f.state.memberList(); + + // Determine the current length of the memberList array. + let size: u32 = memberList.length(); + + // Loop through all indexes of the memberList array. + for (let i: u32 = 0; i < size; i++) { + // Retrieve the next indexed address from the memberList array. + let address: wasmlib.ScAddress = memberList.getAddress(i).value(); + + // Retrieve the factor associated with the address from the members map. + let factor: u64 = members.getUint64(address).value(); + + // Calculate the fair share of tokens to disperse to this member based on the + // factor we just retrieved. Note that the result will be truncated. + let share: u64 = (amount * factor) / totalFactor; + + // Is there anything to disperse to this member? + if (share > 0) { + // Yes, so let's set up an ScTransfer proxy that transfers the + // calculated amount of tokens. + let transfers: wasmlib.ScTransfer = wasmlib.ScTransfer.baseTokens(share); + + // Perform the actual transfer of tokens from the caller allowance + // to the member account. + ctx.transferAllowed(address.asAgentID(), transfers); + } + } +} +``` + + + diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/typedefs.mdx b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/typedefs.mdx new file mode 100644 index 00000000000..2d55e859696 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/typedefs.mdx @@ -0,0 +1,456 @@ +--- +tags: + - containers + - types + - container types + - single type + - array + - schema definition file + +description: You can add a typedefs section to the schema definition file, where you can define a single type name for a container type. This way you can easily create containers that contain container types. + +image: /img/logo/WASP_logo_dark.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Type Definitions + +:::note WasmLib Types + +You can find the complete list of [WasmLib Data Types](../../reference/wasm-lib-data-types.mdx) in the reference section. + +::: + +The WasmLib allows of [container types](../../schema/proxies.mdx#container-proxies), but it +is not possible to specify these types directly because the type name syntax only allows +you to specify a single container type. + +There is a simple solution to this problem. You can add a `typedefs` section to the schema +definition file, where you can define a single type name for a container type. That way +you can easily create containers that contain such container types. The +[Schema Tool](usage.mdx) will automatically generate the in-between proxy types necessary +to make this work. + +To keep it at the `betting` smart contract from [the previous section](structs.mdx), +imagine you want to keep track of all betting rounds. Since a betting round contains an +array of all bets in a round, if it weren't for typedefs you could not define it easily. + +Instead, now you add the following to your schema definition file: + + + + +```yaml +typedefs: + BettingRound: Bet[] // one round of bets +state: + rounds: BettingRound[] // keep track of all betting rounds +``` + + + + +The [Schema Tool](usage.mdx) will generate the following code in `typedefs.xx` for the +`BettingRound` type: + + + + + +```go +import "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/wasmtypes" + +type ArrayOfImmutableBet struct { + proxy wasmtypes.Proxy +} + +func (a ArrayOfImmutableBet) Length() uint32 { + return a.proxy.Length() +} + +func (a ArrayOfImmutableBet) GetBet(index uint32) ImmutableBet { + return ImmutableBet{proxy: a.proxy.Index(index)} +} + +type ImmutableBettingRound = ArrayOfImmutableBet + +type ArrayOfMutableBet struct { + proxy wasmtypes.Proxy +} + +func (a ArrayOfMutableBet) AppendBet() MutableBet { + return MutableBet{proxy: a.proxy.Append()} +} + +func (a ArrayOfMutableBet) Clear() { + a.proxy.ClearArray() +} + +func (a ArrayOfMutableBet) Length() uint32 { + return a.proxy.Length() +} + +func (a ArrayOfMutableBet) GetBet(index uint32) MutableBet { + return MutableBet{proxy: a.proxy.Index(index)} +} + +type MutableBettingRound = ArrayOfMutableBet +``` + + + + +```rust +use wasmlib::*; +use crate::*; + +#[derive(Clone)] +pub struct ArrayOfImmutableBet { + pub(crate) proxy: Proxy, +} + +impl ArrayOfImmutableBet { + pub fn length(&self) -> u32 { + self.proxy.length() + } + + + pub fn get_bet(&self, index: u32) -> ImmutableBet { + ImmutableBet { proxy: self.proxy.index(index) } + } +} + +pub type ImmutableBettingRound = ArrayOfImmutableBet; + +#[derive(Clone)] +pub struct ArrayOfMutableBet { + pub(crate) proxy: Proxy, +} + +impl ArrayOfMutableBet { + + pub fn append_bet(&self) -> MutableBet { + MutableBet { proxy: self.proxy.append() } + } + pub fn clear(&self) { + self.proxy.clear_array(); + } + + pub fn length(&self) -> u32 { + self.proxy.length() + } + + + pub fn get_bet(&self, index: u32) -> MutableBet { + MutableBet { proxy: self.proxy.index(index) } + } +} + +pub type MutableBettingRound = ArrayOfMutableBet; +``` + + + + +```ts +import * as wasmtypes from 'wasmlib/wasmtypes'; +import * as sc from './index'; + +export class ArrayOfImmutableBet extends wasmtypes.ScProxy { + length(): u32 { + return this.proxy.length(); + } + + getBet(index: u32): sc.ImmutableBet { + return new sc.ImmutableBet(this.proxy.index(index)); + } +} + +export class ImmutableBettingRound extends ArrayOfImmutableBet {} + +export class ArrayOfMutableBet extends wasmtypes.ScProxy { + appendBet(): sc.MutableBet { + return new sc.MutableBet(this.proxy.append()); + } + + clear(): void { + this.proxy.clearArray(); + } + + length(): u32 { + return this.proxy.length(); + } + + getBet(index: u32): sc.MutableBet { + return new sc.MutableBet(this.proxy.index(index)); + } +} + +export class MutableBettingRound extends ArrayOfMutableBet {} +``` + + + + +Note how `ImmutableBettingRound` and `MutableBettingRound` type aliases are created +for the types `ArrayOfImmutableBet` and `ArrayOfMutableBet`. These are subsequently used +in the state definition that is generated in `state.xx`: + + + + + +```go +package betting + +import "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib/wasmtypes" + +type ArrayOfImmutableBettingRound struct { + proxy wasmtypes.Proxy +} + +func (a ArrayOfImmutableBettingRound) Length() uint32 { + return a.proxy.Length() +} + +func (a ArrayOfImmutableBettingRound) GetBettingRound(index uint32) ImmutableBettingRound { + return ImmutableBettingRound{proxy: a.proxy.Index(index)} +} + +type ImmutableBettingState struct { + proxy wasmtypes.Proxy +} + +// all bets that were made in this round +func (s ImmutableBettingState) Bets() ArrayOfImmutableBet { + return ArrayOfImmutableBet{proxy: s.proxy.Root(StateBets)} +} + +// current owner of this smart contract +func (s ImmutableBettingState) Owner() wasmtypes.ScImmutableAgentID { + return wasmtypes.NewScImmutableAgentID(s.proxy.Root(StateOwner)) +} + +func (s ImmutableBettingState) Rounds() ArrayOfImmutableBettingRound { + return ArrayOfImmutableBettingRound{proxy: s.proxy.Root(StateRounds)} +} + +type ArrayOfMutableBettingRound struct { + proxy wasmtypes.Proxy +} + +func (a ArrayOfMutableBettingRound) AppendBettingRound() MutableBettingRound { + return MutableBettingRound{proxy: a.proxy.Append()} +} + +func (a ArrayOfMutableBettingRound) Clear() { + a.proxy.ClearArray() +} + +func (a ArrayOfMutableBettingRound) Length() uint32 { + return a.proxy.Length() +} + +func (a ArrayOfMutableBettingRound) GetBettingRound(index uint32) MutableBettingRound { + return MutableBettingRound{proxy: a.proxy.Index(index)} +} + +type MutableBettingState struct { + proxy wasmtypes.Proxy +} + +func (s MutableBettingState) AsImmutable() ImmutableBettingState { + return ImmutableBettingState(s) +} + +// all bets that were made in this round +func (s MutableBettingState) Bets() ArrayOfMutableBet { + return ArrayOfMutableBet{proxy: s.proxy.Root(StateBets)} +} + +// current owner of this smart contract +func (s MutableBettingState) Owner() wasmtypes.ScMutableAgentID { + return wasmtypes.NewScMutableAgentID(s.proxy.Root(StateOwner)) +} + +func (s MutableBettingState) Rounds() ArrayOfMutableBettingRound { + return ArrayOfMutableBettingRound{proxy: s.proxy.Root(StateRounds)} +} +``` + + + + +```rust +use wasmlib::*; + +use crate::*; + +#[derive(Clone)] +pub struct ArrayOfImmutableBettingRound { + pub(crate) proxy: Proxy, +} + +impl ArrayOfImmutableBettingRound { + pub fn length(&self) -> u32 { + self.proxy.length() + } + + + pub fn get_betting_round(&self, index: u32) -> ImmutableBettingRound { + ImmutableBettingRound { proxy: self.proxy.index(index) } + } +} + +#[derive(Clone)] +pub struct ImmutableBettingState { + pub(crate) proxy: Proxy, +} + +impl ImmutableBettingState { + // all bets that were made in this round + pub fn bets(&self) -> ArrayOfImmutableBet { + ArrayOfImmutableBet { proxy: self.proxy.root(STATE_BETS) } + } + + // current owner of this smart contract + pub fn owner(&self) -> ScImmutableAgentID { + ScImmutableAgentID::new(self.proxy.root(STATE_OWNER)) + } + + pub fn rounds(&self) -> ArrayOfImmutableBettingRound { + ArrayOfImmutableBettingRound { proxy: self.proxy.root(STATE_ROUNDS) } + } +} + +#[derive(Clone)] +pub struct ArrayOfMutableBettingRound { + pub(crate) proxy: Proxy, +} + +impl ArrayOfMutableBettingRound { + + pub fn append_betting_round(&self) -> MutableBettingRound { + MutableBettingRound { proxy: self.proxy.append() } + } + pub fn clear(&self) { + self.proxy.clear_array(); + } + + pub fn length(&self) -> u32 { + self.proxy.length() + } + + + pub fn get_betting_round(&self, index: u32) -> MutableBettingRound { + MutableBettingRound { proxy: self.proxy.index(index) } + } +} + +#[derive(Clone)] +pub struct MutableBettingState { + pub(crate) proxy: Proxy, +} + +impl MutableBettingState { + pub fn as_immutable(&self) -> ImmutableBettingState { + ImmutableBettingState { proxy: self.proxy.root("") } + } + + // all bets that were made in this round + pub fn bets(&self) -> ArrayOfMutableBet { + ArrayOfMutableBet { proxy: self.proxy.root(STATE_BETS) } + } + + // current owner of this smart contract + pub fn owner(&self) -> ScMutableAgentID { + ScMutableAgentID::new(self.proxy.root(STATE_OWNER)) + } + + pub fn rounds(&self) -> ArrayOfMutableBettingRound { + ArrayOfMutableBettingRound { proxy: self.proxy.root(STATE_ROUNDS) } + } +} +``` + + + + +```ts +import * as wasmtypes from 'wasmlib/wasmtypes'; +import * as sc from './index'; + +export class ArrayOfImmutableBettingRound extends wasmtypes.ScProxy { + length(): u32 { + return this.proxy.length(); + } + + getBettingRound(index: u32): sc.ImmutableBettingRound { + return new sc.ImmutableBettingRound(this.proxy.index(index)); + } +} + +export class ImmutableBettingState extends wasmtypes.ScProxy { + // all bets that were made in this round + bets(): sc.ArrayOfImmutableBet { + return new sc.ArrayOfImmutableBet(this.proxy.root(sc.StateBets)); + } + + // current owner of this smart contract + owner(): wasmtypes.ScImmutableAgentID { + return new wasmtypes.ScImmutableAgentID(this.proxy.root(sc.StateOwner)); + } + + rounds(): sc.ArrayOfImmutableBettingRound { + return new sc.ArrayOfImmutableBettingRound(this.proxy.root(sc.StateRounds)); + } +} + +export class ArrayOfMutableBettingRound extends wasmtypes.ScProxy { + appendBettingRound(): sc.MutableBettingRound { + return new sc.MutableBettingRound(this.proxy.append()); + } + + clear(): void { + this.proxy.clearArray(); + } + + length(): u32 { + return this.proxy.length(); + } + + getBettingRound(index: u32): sc.MutableBettingRound { + return new sc.MutableBettingRound(this.proxy.index(index)); + } +} + +export class MutableBettingState extends wasmtypes.ScProxy { + asImmutable(): sc.ImmutableBettingState { + return new sc.ImmutableBettingState(this.proxy); + } + + // all bets that were made in this round + bets(): sc.ArrayOfMutableBet { + return new sc.ArrayOfMutableBet(this.proxy.root(sc.StateBets)); + } + + // current owner of this smart contract + owner(): wasmtypes.ScMutableAgentID { + return new wasmtypes.ScMutableAgentID(this.proxy.root(sc.StateOwner)); + } + + rounds(): sc.ArrayOfMutableBettingRound { + return new sc.ArrayOfMutableBettingRound(this.proxy.root(sc.StateRounds)); + } +} +``` + + + + +Notice how the `rounds()` member function returns a proxy to an array of `BettingRound`. +Which in turn is an array of `Bet`. So, the desired result has been achieved. And every +access step only allows you to take the path laid out, which is checked at +compile-time. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/usage.mdx b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/usage.mdx new file mode 100644 index 00000000000..4114e328ccc --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/usage.mdx @@ -0,0 +1,302 @@ +--- +tags: + - functions + - schema tool + - definition file + - Rust + - Go + - init + - json + - yml + +description: The `schema` tool will assist in creating a smart contract as unobtrusively as possible. +image: /img/logo/WASP_logo_dark.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Use the Schema Tool + +Creating smart contracts is simplified using the _Schema Tool_. +This guide outlines the initial steps to set up a new smart contract from scratch. + +## Step 1: Establish a Central Folder + +Select a central folder to house all your smart contracts. +You'll create a separate subfolder for each contract within this central repository. + +Next, choose a descriptive, capitalized camel case name for your contract, like `MySmartContract`. + +## Step 2: Create a Subfolder + +After naming your smart contract, you should create a corresponding subfolder. +Open your terminal, navigate to the central folder, +and initialize your project with the Schema Tool using the following command: + +```shell +schema -init MySmartContract +``` + +This command will create a subfolder named `mysmartcontract` and generate an initial YAML +schema definition file inside this subfolder. Note that the generated subfolder name is +all lower-case. This is to conform to best practices for package names in most languages. +The generated schema definition file looks like this: + + + + +```yaml +name: MySmartContract +description: MySmartContract description +events: {} +structs: {} +typedefs: {} +state: + owner: AgentID // current owner of this smart contract +funcs: + init: + params: + owner: AgentID? // optional owner of this smart contract + setOwner: + access: owner // current owner of this smart contract + params: + owner: AgentID // new owner of this smart contract +views: + getOwner: + results: + owner: AgentID // current owner of this smart contract +``` + + + + +After initializing your project with the Schema Tool, +a pre-populated schema definition file will be generated in the `mysmartcontract` subfolder. +This file contains the necessary sections and functions to manage your smart contract's ownership. + +## Naming Conventions + +Ensure to follow the _camel case_ naming convention in the schema definition file. Here is how to use it: + +- Function and variable names: start with a lowercase letter (e.g., `myFunction`) +- Type names: start with an uppercase letter (e.g., `MyType`) + +## Customizing Fields + +Begin by updating the `description` field with a relevant description of your smart contract. +It is the perfect time to add any known definitions to the necessary sections. + +## Generating Initial Code + +Navigate to your `mysmartcontract` subfolder to generate the initial code for your preferred programming language using +the Schema Tool. + + + + + +If you want to generate Go code, you should run the schema tool with the `-go` option like +this: + +```shell +schema -go +``` + + + + +If you want to generate Rust code, you should run the schema tool with the `-rs` option +like this: + +```shell +schema -rs +``` + + + + +If you want to generate TypeScript code, you should run the schema tool with the `-ts` +option like this: + +```shell +schema -ts +``` + + + + +If you want to generate more than one language your can simply specify multiple options. +For example, to generate both Rust and Go code you would specify both options like this: + +```shell +schema -rs -go +``` + +The schema tool will generate a complete set of source files for the desired language(s), +that will compile successfully into a Wasm code file. You compile these as follows: + + + + + +```shell +tinygo build -target wasm go/main.go +``` + +This will use the Go source files in the go/mysmartcontract subfolder. The only file in +this folder that you should edit manually is `mysmartcontract.go`. All other source files +will be regenerated and overwritten whenever the schema tool is run again. + +See the [TinyGo](https://tinygo.org/) documentation for more build options. + + + + +After generating the Rust code, you should first modify the Cargo.toml file to your +liking, and potentially add the new project to a Rust workspace. Cargo.toml will not be +regenerated once it already exists. Then build the code as follows: + +```shell +wasm-pack build +``` + +This will use Rust source files in the `src` subfolder. The only file in this folder that +you should edit manually is `mysmartcontract.rs`. All other source files will be +regenerated and overwritten whenever the schema tool is run again. + +See the [wasm-pack](https://rustwasm.github.io/wasm-pack/) documentation for more build +options. + + + + +```shell +npx asc ts/mysmartcontract/lib.ts --outFile mysmartcontract_ts.wasm --lib path/to/node_modules +``` + +This will use the TypeScript source files in the ts/mysmartcontract subfolder. The only +file in this folder that you should edit manually is `mysmartcontract.ts`. All other +source files will be regenerated and overwritten whenever the schema tool is run again. + +See the [AssemblyScript](https://www.assemblyscript.org/) documentation for more build +options. + + + + +The generated code is essentially identical for each language, barring some language +idiosyncrasy differences. Just view different language files with the same name next to, +each other, and you will see what we mean. + +Here is an example of the initially generated code, `mysmartcontract.xx` looks like this +before you even start modifying it: + + + + + +```go +package mysmartcontract + +import "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib" + + +func funcInit(ctx wasmlib.ScFuncContext, f *InitContext) { + if f.Params.Owner().Exists() { + f.State.Owner().SetValue(f.Params.Owner().Value()) + return + } + f.State.Owner().SetValue(ctx.RequestSender()) +} + +func funcSetOwner(ctx wasmlib.ScFuncContext, f *SetOwnerContext) { + f.State.Owner().SetValue(f.Params.Owner().Value()) +} + +func viewGetOwner(ctx wasmlib.ScViewContext, f *GetOwnerContext) { + f.Results.Owner().SetValue(f.State.Owner().Value()) +} +``` + + + + +```rust +use wasmlib::*; + +use crate::*; + +pub fn func_init(ctx: &ScFuncContext, f: &InitContext) { + if f.params.owner().exists() { + f.state.owner().set_value(&f.params.owner().value()); + return; + } + f.state.owner().set_value(&ctx.request_sender()); +} + +pub fn func_set_owner(_ctx: &ScFuncContext, f: &SetOwnerContext) { + f.state.owner().set_value(&f.params.owner().value()); +} + +pub fn view_get_owner(_ctx: &ScViewContext, f: &GetOwnerContext) { + f.results.owner().set_value(&f.state.owner().value()); +} +``` + + + + +```ts +import * as wasmlib from 'wasmlib'; +import * as wasmtypes from 'wasmlib/wasmtypes'; +import * as sc from './index'; + +export function funcInit(ctx: wasmlib.ScFuncContext, f: sc.InitContext): void { + if (f.params.owner().exists()) { + f.state.owner().setValue(f.params.owner().value()); + return; + } + f.state.owner().setValue(ctx.requestSender()); +} + +export function funcSetOwner( + ctx: wasmlib.ScFuncContext, + f: sc.SetOwnerContext, +): void { + f.state.owner().setValue(f.params.owner().value()); +} + +export function viewGetOwner( + ctx: wasmlib.ScViewContext, + f: sc.GetOwnerContext, +): void { + f.results.owner().setValue(f.state.owner().value()); +} +``` + + + + +The schema tool automatically generates an initial working version of the functions to maintain the smart contract owner, +catering to most use cases. + +To streamline the building process, configure a build rule in your environment. +This rule should trigger the schema tool with the necessary parameters +whenever there are changes in the schema definition file. +This setup ensures automatic file regeneration, +eliminating the need to run the schema tool manually after each modification. +The tool regenerates code only if it detects alterations since its last operation. +To override this and force regeneration, include the `-force` flag in the command line parameter. + +### Creating Smart Contracts using AssemblyScript + + diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/views.mdx b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/views.mdx new file mode 100644 index 00000000000..b9aef699f09 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/views.mdx @@ -0,0 +1,133 @@ +--- +description: "Explore the characteristics and constraints of view-only functions in smart contracts, +illustrated through a 'getFactor' function example." +tags: +- View-Only Functions +- Smart Contracts +- Call Context +- Immutable Proxies +- Cross-Chain Requests +image: /img/logo/WASP_logo_dark.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Use View-Only Functions + +View-only functions, also known as "views", +are smart contract functions specialized in retrieving state information without altering the smart contract's state. + +## Characteristics + +### Immutable Proxies + +All state storage accesses occur through immutable proxies, ensuring the state remains unchanged. + +### Restricted Functionalities + +Views have a limited [Call Context](../../explanations/context.mdx), +disabling any function that might induce state changes, including token transactions. + +### Intra-chain Calls + +While they can [`call()`](call.mdx) other views within the same chain, +they cannot initiate non-view functions or [`post()`](post.mdx) cross-chain requests. + +### Return Data + +These functions are designed to return data to the caller, as they can't induce any other external effects. + +## Use Case: 'getFactor' Function + +To illustrate the use of view-only functions, consider the `getFactor()` function integrated in the `dividend` smart contract: + + + + + +```go + +// 'getFactor' is a simple View function. It will retrieve the factor +// associated with the (mandatory) address parameter it was provided with. +func viewGetFactor(_ wasmlib.ScViewContext, f *GetFactorContext) { + // Since we are sure that the 'address' parameter actually exists we can + // retrieve its actual value into an ScAddress value type. + var address wasmtypes.ScAddress = f.Params.Address().Value() + + // Create an ScImmutableMap proxy to the 'members' map in the state storage. + // Note that for views this is an *immutable* map as opposed to the *mutable* + // map we can access from the *mutable* state that gets passed to funcs. + var members MapAddressToImmutableUint64 = f.State.Members() + + // Retrieve the factor associated with the address parameter. + var factor uint64 = members.GetUint64(address).Value() + + // Set the factor in the results map of the function context. + // The contents of this results map is returned to the caller of the function. + f.Results.Factor().SetValue(factor) +} +``` + + + + +```rust +// 'getFactor' is a simple View function. It will retrieve the factor +// associated with the (mandatory) address parameter it was provided with. +pub fn view_get_factor(_ctx: &ScViewContext, f: &GetFactorContext) { + + // Since we are sure that the 'address' parameter actually exists we can + // retrieve its actual value into an ScAddress value type. + let address: ScAddress = f.params.address().value(); + + // Create an ScImmutableMap proxy to the 'members' map in the state storage. + // Note that for views this is an *immutable* map as opposed to the *mutable* + // map we can access from the *mutable* state that gets passed to funcs. + let members: MapAddressToImmutableUint64 = f.state.members(); + + // Retrieve the factor associated with the address parameter. + let factor: u64 = members.get_uint64(&address).value(); + + // Set the factor in the results map of the function context. + // The contents of this results map is returned to the caller of the function. + f.results.factor().set_value(factor); +} +``` + + + + +```ts +// 'getFactor' is a simple View function. It will retrieve the factor +// associated with the (mandatory) address parameter it was provided with. +export function viewGetFactor( + ctx: wasmlib.ScViewContext, + f: sc.GetFactorContext, +): void { + // Since we are sure that the 'address' parameter actually exists we can + // retrieve its actual value into an ScAddress value type. + let address: wasmlib.ScAddress = f.params.address().value(); + + // Create an ScImmutableMap proxy to the 'members' map in the state storage. + // Note that for views this is an *immutable* map as opposed to the *mutable* + // map we can access from the *mutable* state that gets passed to funcs. + let members: sc.MapAddressToImmutableUint64 = f.state.members(); + + // Retrieve the factor associated with the address parameter. + let factor: u64 = members.getUint64(address).value(); + + // Set the factor in the results map of the function context. + // The contents of this results map is returned to the caller of the function. + f.results.factor().setValue(factor); +} +``` + + + + +The return values are passed to the caller through the predefined [Results](results.mdx) map +associated with the [Call Context](../../explanations/context.mdx). +Again, this works the same as for Funcs, although Funcs do not necessarily return values to the caller. The +[Schema Tool](usage.mdx) will generate a function-specific [Results](results.mdx) +structure with type-safe proxies to the result fields in this map. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/yaml.mdx b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/yaml.mdx new file mode 100644 index 00000000000..c812b5d6cea --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/yaml.mdx @@ -0,0 +1,69 @@ +--- +tags: + - definition + - yaml + - smart contract creator + - one-time + - contract generation + - datatypes +description: the syntax of a schema definition file will be described here. +image: /img/logo/WASP_logo_dark.png +--- + +# YAML Schema Definition: Level 1 Attributes + +The schema definition file can have the following level 1 attributes: + +## name + +- **Type**: Single string +- **Usage**: Dictates the package name for the smart contract + +## description + +- **Type**: Single string +- **Usage**: Describes the smart contract's functionality (currently not utilized in the final smart contract) + +## events + +- **Type**: Map of strings +- **Usage**: Define structured events ([more info](./events.mdx)) +- **Restriction**: Field data types must be primitive; arrays, maps, or typedefs are not allowed + +## structs + +- **Type**: Map of string maps +- **Usage**: Declare structs for future development, usable in schema definitions +- **Restriction**: Fields must hold primitive types; arrays, maps, or typedef aliases are prohibited + +## typedefs + +- **Type**: Map of strings +- **Usage**: Create aliases for primitive values; supports primitive values, maps of primitive values, or arrays of primitive values +- **Restriction**: Nested typedefs are not permissible + +## state + +- **Type**: Map of strings +- **Usage**: Contains key/value pairs for use-case specific data ([details](../../explanations/states.md)) +- **Note**: To employ nested types, create a typedef alias for arrays or maps, but ensure map keys are primitive + +## funcs & views + +Describe functions and views sharing the same parameter and result names, ensuring they adhere to identical data types. The attributes common to both are: + +- **`access`** +- **Requirement**: Must be a state variable +- **Details**: Defines access permissions ([read more](./access.mdx#limiting-access)) + +- **`params`** +- **Type**: Can vary — array, map, or typedef alias +- **Usage**: Specifies input parameters + +- **`results`** +- **Type**: Can vary — array, map, or typedef alias +- **Usage**: Designates return values + +### Special Note on `funcs` + +- **Reserved Keyword**: `init` — relates to a distinct function ([explore](./init.mdx)) diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/introduction.mdx b/docs/content/guides/developer/layer-2-smart-contracts/schema/introduction.mdx new file mode 100644 index 00000000000..de35b4c364a --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/schema/introduction.mdx @@ -0,0 +1,62 @@ +# The Schema Tool + +Smart contracts need robustness, combining both flexibility and stringent regulation to prevent mistakes and foster efficiency. +Using the Schema Tool ensures consistency, and simplifies smart contract development. + +## Why Use the Schema Tool? + +### Ensure Robustness and Consistency + +By employing a code generator rooted in a schema definition file, you achieve: + +- **Reliability**: Through debugged, trustworthy generated code. +- **Adaptability**: Facilitating modifications in the smart contract interface. +- **Intent Reflection**: Enforcing defined smart contract behavior at compile-time. +- **Multilingual Support**: Accommodating various programming languages. + +### Prevent Repetitive Coding + +Initial experiences illustrated repetitive coding in: + +- `on_load` function setup and maintenance. +- Function access rights verification. +- Function parameter type and presence confirmation. +- Establishing access to State, Params, and Results maps. +- Common string constant definitions. + +The schema tool diminishes redundancy and ensures up-to-date functionalities. + +## The Schema Definition File + +### Defining a Clear Interface + +The schema definition file serves as a single source of truth, encompassing crucial details like: + +- State Storage Variables. +- [Funcs and Views](../../explanations/context). +- [Access rights](how-tos/access.mdx). +- [Input parameters](how-tos/params.mdx) and [output results](how-tos/results.mdx) . +- Additional Data Structures. + +### Automation with Schema Tool + +Using the [Schema Tool](how-tos/usage.mdx), the file facilitates: + +- **Skeleton Generation**: Crafting a smart contract framework that needs function implementations. +- **Interface Generation**: Creating interfaces to functions with stringent compile-time type-checking, thereby reducing errors. + +## Benefits of Schema Tool in Smart Contracts + +### Centralized Information + +Having all pertinent details in one place allows: + +- **Uniform Function Calls**: Through a generated interface used by client-side code. +- **Error Minimization**: Via compile-time type-checking. + +### Efficiency and Simplicity + +Knowledge of all essential aspects leads to: + +- **Constant Generation**: Avoiding typo-prone key strings repetition and precalculating essential values like `Hnames`. +- **Informative Code**: Generating code to correctly notify the host about available `Funcs` and `Views`. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/proxies.mdx b/docs/content/guides/developer/layer-2-smart-contracts/schema/proxies.mdx new file mode 100644 index 00000000000..0459da5c0bf --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/schema/proxies.mdx @@ -0,0 +1,76 @@ +--- +tags: + - proxies + - sandbox + - wasm + - value proxies + - container proxies + - array proxies + - map proxies + - explanation +description: As there is no way for the Wasm code to access any memory outside its own memory space, the WasmLib interface provides a number of proxies to make accessing data within the ISC sandbox as seamless as possible. +image: /img/wasm_vm/Proxies.png +--- +# Data Access Proxies + +To interact seamlessly with the ISC sandbox's regulated environment and facilitate smart contract data access, +the WasmLib introduces data access proxies. +Proxies are objects that can perform the underlying data transfers between the +separate systems. + +## Overview + +The restrictive ISC sandbox environment requires an intermediary, or a library, to access sandbox functionalities — a role that the WasmLib fulfills through data access `proxies`. +These entities stand as bridges, enabling data transfers between segregated systems, providing a streamlined pathway to interact with smart contract data stored on the ISC host. + +## The Role of Proxies + +Proxies refer to actual objects or values housed in the ISC host, +essentially acting as data references that understand how to manipulate the data they represent. +At the core, data is secured in maps on the ISC host with byte strings serving as both keys and values. + +The WasmLib recognizes three predefined maps: + +- **[State Map](../schema/how-tos/state.mdx):** A repository for all state storage values. +- **[Params Map](../schema/how-tos/params.mdx):** Holds the parameter values of the current function call. +- **[Results Map](../schema/how-tos/results.mdx):** Returns the result values of the function call. + +Through these maps, a complex, +JSON-like data structure can be created with the aid of the [Schema Tool](../schema/how-tos/usage.mdx), +although, fundamentally, this structure is rooted in simple key-value access on the underlying map. + +## Proxy Varieties + +Proxies are segmented into various categories to facilitate different functionalities, including value proxies and container proxies. + +### Value Proxies + +Representing a single instance of a predetermined data type, +value proxies are basic entities facilitating type conversion of the byte string representing the stored value. + +The [Schema Tool](../schema/how-tos/usage.mdx) ensures type-safe code generation, always selecting the suitable proxy type. + +### Container Proxies + +Container proxies offer a virtual nesting system on the underlying map, +creating paths leading to value proxies housed in a virtual container. +They use JSON and YAML nesting patterns, and there are two primary types: + +#### 1. Map Proxies + +- **Root Maps:** Encase any element type but restrict keys to human-readable strings, which are defined in the schema definition file. +- **Virtual Maps:** Resides under a root map and accommodates values of a single associated data type. + +#### 2. Array Proxies + +- Operate as a specialized map where the key is an Int32 value, forming a sequence from 0 to N-1 for an array harboring N elements. + +## Proxies in Action + +![Proxies in WasmLib](/img/wasm_vm/Proxies.png) + +In the illustration, we see the key-value combinations (Key 1 to Key 4) in the ISC state storage map. Key 4 directs us to an array containing indexed values ranging from 0 to N. + +Notice the precise reflection of these elements in the WasmLib proxies, +which maintain a container proxy for every container and a value proxy for each stored value. +However, it is not obligatory for a smart contract function to define a proxy for every value or container in the ISC state storage. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/getting-started.md b/docs/content/guides/developer/layer-2-smart-contracts/solo/getting-started.md new file mode 100644 index 00000000000..6fe73a027ce --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/solo/getting-started.md @@ -0,0 +1,80 @@ +--- +description: 'Solo is a testing framework that allows developers to validate real smart contracts and entire inter-chain +protocols.' +image: /img/logo/WASP_logo_dark.png +tags: + +- testing framework +- golang +- rust +- inter-chain protocols +- validate smart contracts +- install +- how-tos +--- + +# Testing Smart Contracts with Solo + +## What is Solo? + +[_Solo_](https://github.com/iotaledger/wasp/tree/develop/packages/solo) is a testing framework that allows developers to +validate real smart contracts and entire inter-chain protocols before deploying them on the distributed network. + +## Installation + +### Prerequisites + +[Go (version 1.20)](https://tip.golang.org/doc/go1.20). As _Solo_ tests are written in Go, you must +[install Go](https://go.dev/doc/install). + +### Access the Solo Framework + +You can access the Solo package by cloning the [Wasp repository](#clone-the-wasp-repository) +or [installing the Solo package](#install-the-solo-package). + +#### Clone the Wasp Repository + +_Solo_ is part of the [_Wasp_ codebase repository](https://github.com/iotaledger/wasp.git). You can access the Solo +framework by cloning the repository with the following command: + +```shell +git clone https://github.com/iotaledger/wasp.git +``` + +After you have cloned the repository, you can access the Solo package in the `/packages/solo` folder. + +#### Install the Solo Package + +You can install the Solo package separately using the following command: + +```shell +go get github.com/iotaledger/wasp/packages/solo +``` + +:::tip Go Docs + +You can browse the Solo Go API reference (updated to the `master` branch) in +[go-docs](https://pkg.go.dev/github.com/iotaledger/wasp/packages/solo). + +::: + +### Example Contracts + +You will need a smart contract to test along with Solo. +You can find example implementations of Wasm smart contracts, including source code and tests, in the Wasp +repository’s [contracts/wasm folder](https://github.com/iotaledger/wasp/tree/develop/contracts/wasm). + +The following sections will present some Solo usage examples. You can find the example code in +the [Wasp repository](https://github.com/iotaledger/wasp/tree/develop/documentation/tutorial-examples). + +### Run `*_test` Files + +You can run `*_test` files by moving to their directory and running the following command: + +```shell +go test +``` + +If you run this command from the `/documentation/tutorial-examples` folder, you will run the +[Tutorial Test](https://github.com/iotaledger/wasp/blob/develop/documentation/tutorial-examples/test/tutorial_test.go), +which contains all the examples explained in the following sections. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/deploying-sc.md b/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/deploying-sc.md new file mode 100644 index 00000000000..387e4d18235 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/deploying-sc.md @@ -0,0 +1,70 @@ +--- +description: Deploying Wasm smart contracts with Solo. +image: /img/tutorial/send_request.png +tags: + - testing + - PostRequestSync + - PostRequestOffLedger + - send + - requests + - post + - solo + - on-ledger + - off-ledger + - how-tos +--- + +# Deploying Wasm Smart Contracts + +:::note WASM VM + +For more information about how to create Wasm smart contracts, refer to the [Wasm VM chapter](../../getting-started/languages-and-vms.md#wasm-vm-for-isc). + +::: + +## Deploy the Solo Tutorial + +The following examples will make use of the +[`solotutorial` Rust/Wasm smart contract](https://github.com/iotaledger/wasp/tree/develop/documentation/tutorial-examples). + +In order to test the smart contract using Solo, first you need to deploy it. You can use the following code to +deploy `solotutorial_bg.wasm`: + +```go +func TestTutorialDeploySC(t *testing.T) { + env := solo.New(t, &solo.InitOptions{AutoAdjustStorageDeposit: true}) + chain := env.NewChain() + err := chain.DeployWasmContract(nil, "solotutorial", "solotutorial_bg.wasm") + require.NoError(t, err) +} +``` + +This will work as long as the `solotutorial_bg.wasm` file is in the same directory as the Go test code. + +### Create a Default Wallet and Chain + +You can use the `NewChain()` function to create a new wallet and deploys a new chain using said wallet, and other +default parameters. You can access the wallet calling `chain.OriginatorPrivateKey`. + +### DeployWasmContract Parameters + +#### Deployer's Key Pair + +The first parameter to `DeployWasmContract` is the key pair of the deployer of the smart contract. You can pass `nil` +to use a default wallet, which can be accessed as `chain.OriginatorPrivateKey`. + +#### Smart Contract Name + +The second parameter to `DeployWasmContract` (`"solotutorial"`), is the name assigned to the smart contract instance. +Smart contract instance names must be unique across each chain. + +### AutoAdjustStorageDeposit + +In the example above we enabled the `AutoAdjustStorageDeposit` option. +This is necessary in order to automatically adjust all sent L1 transactions to include the storage deposit if +necessary (provided that the sender owns the funds). + +It is possible to disable the option and have manual control of the storage deposit, but in that case the deployment +of the smart contract will have to be done "by hand". + +In most cases it is recommended to leave it enabled. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/error-handling.md b/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/error-handling.md new file mode 100644 index 00000000000..40b414feedc --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/error-handling.md @@ -0,0 +1,51 @@ +--- +description: What happens when a smart contract invocation fails? +image: /img/logo/WASP_logo_dark.png +tags: + - testing + - solo + - error handling + - panic + - state + - transition +--- + +# Error Handling + +The following test posts a request to the `solotutorial` smart contract without the expected parameter `"str"`, causing +the smart contract call to panic: + +```go +func TestTutorialInvokeSCError(t *testing.T) { + env := solo.New(t, &solo.InitOptions{AutoAdjustStorageDeposit: true}) + chain := env.NewChain() + err := chain.DeployWasmContract(nil, "solotutorial", "solotutorial_bg.wasm") + require.NoError(t, err) + + // missing the required parameter "str" + req := solo.NewCallParams("solotutorial", "storeString"). + WithMaxAffordableGasBudget() + + _, err = chain.PostRequestSync(req, nil) + require.Error(t, err) + require.True(t, err.Error() == "WASM: panic in VM: missing mandatory string") +} +``` + +The `_, err = chain.PostRequestSync(req, nil)` will return an error containing `WASM: panic in VM: missing mandatory string`. + +This shows that the request resulted in a panic. +The Solo test passes because of the `require.Error(t, err)` line. + +Note that this test still ends with the state `#4`, although the last request to the smart contract failed: + +```log +20:09.974258867 INFO TestTutorialInvokeSCError.ch1 solo/run.go:156 state transition --> #4. Requests in the block: 1. Outputs: 1 +``` + +This shows that a chain block is always generated, regardless of whether the smart contract call succeeds or not. The +result of the request is stored in the chain's [`blocklog`](../../reference/core-contracts/blocklog.md) in the form of +a receipt. In fact, the received Go error `err` in the test above is just generated from the request receipt. + +If a panic occurs during a smart contract call, it is recovered by the VM context, and the request is marked as failed. +Any state changes made prior to the panic are rolled back. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/examples.mdx b/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/examples.mdx new file mode 100644 index 00000000000..c924b0b67fe --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/examples.mdx @@ -0,0 +1,282 @@ +--- +tags: + - solo + - testing + - errors + - member function + - post + - ctx + - divide function + - error message + +description: Use the SoloContext to create full-blown tests for the dividend example smart contract. + +image: /img/logo/WASP_logo_dark.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Example Tests + +In the previous sections we showed how you can [`call()`](../../schema/how-tos/call.mdx) or +[`post()`](../../schema/how-tos/post.mdx) smart contract function requests. We also created a few wrapper +functions to simplify calling these functions even further. Now we will look at how to use +the SoloContext to create full-blown tests for the `dividend` example smart contract. + +Let's start with a simple test. We are going to use the `member` function to add a valid +new member/factor combination to the member group. + + + + + +```go +func TestAddMemberOk(t *testing.T) { + ctx := wasmsolo.NewSoloContext(t, dividend.ScName, dividend.OnDispatch) + + member1 := ctx.NewSoloAgent("member1") + dividendMember(ctx, member1, 100) + require.NoError(t, ctx.Err) +} +``` + + + + +The above test first deploys the `dividend` smart contract to a new chain, and returns a +SoloContext `ctx`. Then it uses `ctx` to create a new SoloAgent `member1`. When creating a +SoloAgent a new _Tangle_ address is created for that agent and its on-chain account is +pre-seeded with 10M base tokens so that it is ready to be used in tests. The SoloAgent can +be used whenever an address or agent ID needs to be provided, it can be used to sign a +request to identify it as the sender, and it can be used to inspect the asset balances on +its Tangle address and its on-chain account. + +In this case, we simply create `member1`, and pass it to the dividend contract's `member` +function, which will receive the address of `member1` and a dispersal factor of 100. +Finally, we check if ctx has received an error during the execution of the call. Remember +that the only way to pass an error from a WasmLib function call is through a `panic()` +call. The code that handles the actual call will intercept any `panic()` that was raised, +and return an error. The SoloContext saves this error for later inspection, because the +function descriptor used in the call itself has no way of passing back this error. + +The next two example tests each call the contract's `member` function in the exact same +way, but in both cases one required parameter is omitted. The idea is to test that the +function properly panics by checking the ctx.Err value is not nil after the call. Finally, +the error message text is checked to see if it contains the expected error message. + + + + + +```go +func TestAddMemberFailMissingAddress(t *testing.T) { + ctx := wasmsolo.NewSoloContext(t, dividend.ScName, dividend.OnDispatch) + + member := dividend.ScFuncs.Member(ctx) + member.Params.Factor().SetValue(100) + member.Func.Post() + require.Error(t, ctx.Err) + require.Contains(t, ctx.Err.Error(), "missing mandatory address") +} + +func TestAddMemberFailMissingFactor(t *testing.T) { + ctx := wasmsolo.NewSoloContext(t, dividend.ScName, dividend.OnDispatch) + + member1 := ctx.NewSoloAgent("member1") + member := dividend.ScFuncs.Member(ctx) + member.Params.Address().SetValue(member1.ScAgentID().Address()) + member.Func.Post() + require.Error(t, ctx.Err) + require.Contains(t, ctx.Err.Error(), "missing mandatory factor") +} +``` + + + + +Each test has to set up the chain/contract/context from scratch. We will often use a +specific setupTest() function to do all setup work that is shared by many tests. + +We cannot use the `dividendMember` wrapper function in these two tests because of the +missing required function parameters. So we have simply copy/pasted the code, and removed +the `Params` proxy initialization lines that we wanted to be detected as missing. + +Now let's see a more complex example: + + + + + +```go +func TestDivide1Member(t *testing.T) { + ctx := wasmsolo.NewSoloContext(t, dividend.ScName, dividend.OnDispatch) + + member1 := ctx.NewSoloAgent("member1") + bal := ctx.Balances(member1) + + dividendMember(ctx, member1, 100) + require.NoError(t, ctx.Err) + + bal.Chain += ctx.GasFee + bal.Originator += ctx.StorageDeposit - ctx.GasFee + bal.VerifyBalances(t) + + const dividendToDivide = 1*isc.Million + 1 + dividendDivide(ctx, dividendToDivide) + require.NoError(t, ctx.Err) + + bal.Chain += ctx.GasFee + bal.Originator -= ctx.GasFee + bal.Add(member1, dividendToDivide) + bal.VerifyBalances(t) +} +``` + + + + +The first half of the code is almost identical to our first test above. We set up the +test, create an agent, set the factor for that agent to 100, and verify that no error +occurred. Notice how we additionally call `ctx.Balances()` to make a snapshot of all the +original asset balances including those of the agent. + +Then in the next lines we update the asset balances with the changes we expect to happen +because of the call to the `member` function. And then we verify these changes against the +actual asset balances by calling `bal.VerifyBalances(t)`. + +Next we transfer 1M + 1 tokens as part of the post request to the `divide` function. We +subsequently check that no error has occurred. Finally, we again modify the asset balances +to reflect the expected changes and verify these changes against the actual asset +balances. + +Now let's skip to the most complex test of all: + + + + + +```go + func TestDivide3Members(t *testing.T) { + ctx := wasmsolo.NewSoloContext(t, dividend.ScName, dividend.OnDispatch) + + member1 := ctx.NewSoloAgent("member1") + bal := ctx.Balances(member1) + + dividendMember(ctx, member1, 25) + require.NoError(t, ctx.Err) + + bal.Chain += ctx.GasFee + bal.Originator += ctx.StorageDeposit - ctx.GasFee + bal.VerifyBalances(t) + + member2 := ctx.NewSoloAgent("member2") + bal = ctx.Balances(member1, member2) + + dividendMember(ctx, member2, 50) + require.NoError(t, ctx.Err) + + bal.Chain += ctx.GasFee + bal.Originator += ctx.StorageDeposit - ctx.GasFee + bal.VerifyBalances(t) + + member3 := ctx.NewSoloAgent() + bal = ctx.Balances(member1, member2, member3) + + dividendMember(ctx, member3, 75) + require.NoError(t, ctx.Err) + + bal.Chain += ctx.GasFee + bal.Originator += ctx.StorageDeposit - ctx.GasFee + bal.VerifyBalances(t) + + const dividendToDivide = 2*isc.Million - 1 + dividendDivide(ctx, dividendToDivide) + require.NoError(t, ctx.Err) + + remain := dividendToDivide - dividendToDivide*25/150 - dividendToDivide*50/150 - dividendToDivide*75/150 + bal.Chain += ctx.GasFee + bal.Originator += remain - ctx.GasFee + bal.Add(member1, dividendToDivide*25/150) + bal.Add(member2, dividendToDivide*50/150) + bal.Add(member3, dividendToDivide*75/150) + bal.VerifyBalances(t) + + const dividendToDivide2 = 2*isc.Million + 234 + dividendDivide(ctx, dividendToDivide2) + require.NoError(t, ctx.Err) + + remain = dividendToDivide2 - dividendToDivide2*25/150 - dividendToDivide2*50/150 - dividendToDivide2*75/150 + bal.Chain += ctx.GasFee + bal.Originator += remain - ctx.GasFee + bal.Add(member1, dividendToDivide2*25/150) + bal.Add(member2, dividendToDivide2*50/150) + bal.Add(member3, dividendToDivide2*75/150) + bal.VerifyBalances(t) +} +``` + + + + +This function creates 3 agents, and associates factors of 25, 50, and 75 respectively to +them. That required 3 `member` requests, and we verify the expected balance changes after +each request. Next the `divide` function is called, with 2M-1 tokens passed to it. + +After this we verify that each agent has been distributed tokens according to its relative +factor. Those factors are 25/150th, 50/150th, and 75/150th, respectively. Note that we +cannot transfer fractional tokens, so we truncate to the nearest integer and ultimately +any remaining tokens are not transferred, but remain in the sender's account. + +Finally, we call `divide` again with 2M+234 tokens and again verify the asset balances +afterwards. + +Next we will show how to test [Views](../../schema/how-tos/views.mdx) and/or [Funcs](../../schema/how-tos/funcs.mdx) that return +a result. Note that even though Funcs are usually invoked through a [`post()`](../../schema/how-tos/post.mdx) +request, in which case any return values are inaccessible, they still can be invoked +through a [call()](../../schema/how-tos/call.mdx) from within another Func, in which these return values can +be used normally. Since solo executes [`post()`](../../schema/how-tos/post.mdx) requests synchronously, it is +possible to have a Func return a result and test for certain result values. + + + + + +```go +func TestGetFactor(t *testing.T) { + ctx := wasmsolo.NewSoloContext(t, dividend.ScName, dividend.OnDispatch) + + member1 := ctx.NewSoloAgent("member1") + dividendMember(ctx, member1, 25) + require.NoError(t, ctx.Err) + + member2 := ctx.NewSoloAgent("member2") + dividendMember(ctx, member2, 50) + require.NoError(t, ctx.Err) + + member3 := ctx.NewSoloAgent() + dividendMember(ctx, member3, 75) + require.NoError(t, ctx.Err) + + value := dividendGetFactor(ctx, member3) + require.NoError(t, ctx.Err) + require.EqualValues(t, 75, value) + + value = dividendGetFactor(ctx, member2) + require.NoError(t, ctx.Err) + require.EqualValues(t, 50, value) + + value = dividendGetFactor(ctx, member1) + require.NoError(t, ctx.Err) + require.EqualValues(t, 25, value) +} +``` + + + + +Here we first set up the same 3 dispersion factors, and then we retrieve the dispersion +factors for each member in reverse order and verify their values. + +In the [next section](timelock.mdx) we will describe a few more helper member functions +of the SoloContext. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/first-example.md b/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/first-example.md new file mode 100644 index 00000000000..f4189cee840 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/first-example.md @@ -0,0 +1,94 @@ +--- +description: Example of a _Solo_ test. It deploys a new chain and invokes some view calls. +image: /img/logo/WASP_logo_dark.png +tags: + - testing framework + - golang + - solo + - example + - new chain + - how-tos +--- + +# First Example + +The following is an example of a _Solo_ test. It deploys a new chain and invokes some view calls in the +[`root`](../../reference/core-contracts/root.md) and [`governance`](../../reference/core-contracts/governance.md) +[core contracts](../../reference/core-contracts/overview.md). + +```go +import ( + "testing" + + "github.com/iotaledger/wasp/packages/solo" + "github.com/iotaledger/wasp/packages/vm/core/corecontracts" + "github.com/stretchr/testify/require" +) + +func TestTutorialFirst(t *testing.T) { + env := solo.New(t) + chain := env.NewChain() + + // calls views governance::ViewGetChainInfo and root:: ViewGetContractRecords + chainID, chainOwnerID, coreContracts := chain.GetInfo() + // assert that all core contracts are deployed + require.EqualValues(t, len(corecontracts.All), len(coreContracts)) + + t.Logf("chain ID: %s", chainID.String()) + t.Logf("chain owner ID: %s", chainOwnerID.String()) + for hname, rec := range coreContracts { + t.Logf(" Core contract %q: %s", rec.Name, hname) + } +} +``` + +The output of the test will be something like this: + +```log +=== RUN TestTutorialFirst +29:43.383770108 INFO TestTutorialFirst.db dbmanager/dbmanager.go:64 creating new in-memory database for: CHAIN_REGISTRY +29:43.383957435 INFO TestTutorialFirst solo/solo.go:162 Solo environment has been created: logical time: 00:01.001000000, time step: 1ms +29:43.384671943 INFO TestTutorialFirst solo/solo.go:236 deploying new chain 'tutorial1'. ID: tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd, state controller address: tgl1qpk70349ftcpvlt6lnn0437p63wt7w2ejvlkw93wkkt0kc39f2wpvuv73ea +29:43.384686865 INFO TestTutorialFirst solo/solo.go:238 chain 'tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd'. state controller address: tgl1qpk70349ftcpvlt6lnn0437p63wt7w2ejvlkw93wkkt0kc39f2wpvuv73ea +29:43.384698704 INFO TestTutorialFirst solo/solo.go:239 chain 'tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd'. originator address: tgl1qq93jh7dsxq3lznajgtq33v26rt0pz0rs0rwar4jahahp6h2hh9jy4nc52k +29:43.384709967 INFO TestTutorialFirst.db dbmanager/dbmanager.go:64 creating new in-memory database for: tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd +29:43.384771911 INFO TestTutorialFirst solo/solo.go:244 chain 'tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd'. origin state commitment: c4f09061cd63ea506f89b7cbb3c6e0984f124158 +29:43.417023624 INFO TestTutorialFirst solo/solo.go:171 solo publisher: state [tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd 1 1 0-6c7ff6bc5aaa3af12f9b6b7c43dcf557175ac251418df562f7ec4ff092e84d4f 0000000000000000000000000000000000000000000000000000000000000000] +29:43.417050354 INFO TestTutorialFirst solo/solo.go:171 solo publisher: request_out [tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd 0-11232aa47639429b83faf79547c6bf615bd65aa461f243c89e4073b792ac89b7 1 1] +29:43.417056290 INFO TestTutorialFirst.tutorial1 solo/run.go:156 state transition --> #1. Requests in the block: 1. Outputs: 1 +29:43.417179099 INFO TestTutorialFirst.tutorial1 solo/run.go:176 REQ: 'tx/0-11232aa47639429b83faf79547c6bf615bd65aa461f243c89e4073b792ac89b7' +29:43.417196814 INFO TestTutorialFirst.tutorial1 solo/solo.go:301 chain 'tutorial1' deployed. Chain ID: tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd + tutorial_test.go:20: chain ID: tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd + tutorial_test.go:21: chain owner ID: tgl1qq93jh7dsxq3lznajgtq33v26rt0pz0rs0rwar4jahahp6h2hh9jy4nc52k + tutorial_test.go:23: Core contract "blob": fd91bc63 + tutorial_test.go:23: Core contract "governance": 17cf909f + tutorial_test.go:23: Core contract "errors": 8f3a8bb3 + tutorial_test.go:23: Core contract "evm": 07cb02c1 + tutorial_test.go:23: Core contract "accounts": 3c4b5e02 + tutorial_test.go:23: Core contract "root": cebf5908 + tutorial_test.go:23: Core contract "blocklog": f538ef2b +--- PASS: TestTutorialFirst (0.03s) +``` + +:::note + +- The example uses [`stretchr/testify`](https://github.com/stretchr/testify) for assertions, but it is not strictly + required. +- Addresses, chain IDs and other hashes should be the same on each run of the test because Solo uses a constant seed by + default. +- The timestamps shown in the log come from the computer's timer, but the Solo environment operates on its own logical + time. + +::: + +The [core contracts](../../reference/core-contracts/overview.md) listed in the log are automatically deployed on each +new chain. The log also shows their _contract IDs_. + +The output fragment in the log `state transition --> #1` means that the state of the chain has changed from block index +0 (the origin index of the empty state) to block index 1. State #0 is the empty origin state, and #1 always contains all +core smart contracts deployed on the chain, as well as other data internal to the chain itself, such as the _chainID_ +and the _chain owner ID_. + +The _chain ID_ and _chain owner ID_ are, respectively, the ID of the deployed chain, and the address of the L1 account +that triggered the deployment of the chain (which is automatically generated by Solo in our example, but it can be +overridden when calling `env.NewChain`). diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/invoking-sc.md b/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/invoking-sc.md new file mode 100644 index 00000000000..ec60f2d2cbe --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/invoking-sc.md @@ -0,0 +1,116 @@ +--- +description: Invoking smart contracts with on-ledger and off-ledger requests with Solo. +image: /img/tutorial/send_request.png +tags: + - how-to + - explanation + - testing + - PostRequestSync + - PostRequestOffLedger + - send + - requests + - post + - solo + - on-ledger + - off-ledger +--- + +# Invoking Smart Contracts + +After deploying +the [`solotutorial`](https://github.com/iotaledger/wasp/tree/develop/documentation/tutorial-examples) +smart contract, you can invoke the `storeString` function: + +```go +func TestTutorialInvokeSC(t *testing.T) { + env := solo.New(t, &solo.InitOptions{AutoAdjustStorageDeposit: true}) + chain := env.NewChain() + err := chain.DeployWasmContract(nil, "solotutorial", "solotutorial_bg.wasm") + require.NoError(t, err) + + // invoke the `storeString` function + req := solo.NewCallParams("solotutorial", "storeString", "str", "Hello, world!"). + WithMaxAffordableGasBudget() + _, err = chain.PostRequestSync(req, nil) + require.NoError(t, err) + + // invoke the `getString` view + res, err := chain.CallView("solotutorial", "getString") + require.NoError(t, err) + require.Equal(t, "Hello, world!", codec.MustDecodeString(res.MustGet("str"))) +} +``` + +## Parameters + +### `NewCallParams()` + +The above example uses `NewCallParams` to set up the parameters of the request that it will send to the contract. +It specifies that it wants to invoke the `storeString` entry point of the `solotutorial` smart contract, passing the +parameter named `str` with the string value `"Hello, world!"`. + +### `WithMaxAffordableGasBudget()` + +`WithMaxAffordableGasBudget()` assigns the gas budget of the request to the maximum that the sender can afford with the +funds they own on L2 (including any funds attached in the request itself). +In this case the funds attached automatically for the storage deposit will be enough to cover for the gas fee, so it is +not necessary to manually deposit more funds for gas. + +## `PostRequestSync()` + +`PostRequestSync` sends an on-ledger request to the chain. + +## On-Ledger Requests + +[![Generic process of posting an on-ledger request to the smart contract](/img/tutorial/send_request.png)](/img/tutorial/send_request.png) + +The diagram above depicts the generic process of posting an _on-ledger_ request to the smart contract. +The same diagram is valid for the Solo environment and any other requester that sends an on-ledger request, e.g., the +IOTA Smart Contracts wallet or another chain. + +Posting an on-ledger request always consists of the steps below. +Note that in Solo, all seven steps are carried out by a single call to `PostRequestSync`. + +1. Create the L1 transaction, which wraps the L2 request and moves tokens. + + Each on-ledger request must be contained in a transaction on the ledger. + Therefore, it must be signed by the sender’s private key. + This securely identifies each requester in IOTA Smart Contracts. + In Solo, the transaction is signed by the private key provided in the second parameter of the `PostRequestSync` call + (`chain.OriginatorPrivateKey()` by default). + +2. Post and confirm the transaction to the L1 ledger. + + In Solo, it is just adding the transaction to the emulated L1 ledger, so it is confirmed immediately and + synchronously. + The confirmed transaction on the ledger becomes part of the backlog of requests to be processed by the chain. + In the real L1 ledger, the sender must wait until the ledger confirms the transaction. + +3. The chain picks the request from the backlog and runs the request on the VM. +4. The _VM_ calls the target entry point of the smart contract program. The program updates the state. +5. The VM produces a state update transaction (the _anchor_). +6. The chain signs the transaction with its private key (the `chain.StateControllerKeyPair()` in Solo). +7. The chain posts the resulting transaction to the L1 ledger and, after confirmation, commits the corresponding state. + +The following lines in the test log correspond to step 7: + +```log +49:37.771863573 INFO TestTutorialInvokeSC solo/solo.go:171 solo publisher: state [tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd 4 1 0-177c8a62feb7d434608215a179dd6637b8038d1237dd264 +d8feaf4d9a851b808 0000000000000000000000000000000000000000000000000000000000000000] +49:37.771878833 INFO TestTutorialInvokeSC solo/solo.go:171 solo publisher: request_out [tgl1pzehtgythywhnhnz26s2vtpe2wy4y64pfcwkp9qvzhpwghzxhwkps2tk0nd 0-c55b41b07687c644b7f7a1b9fb5da86f2d40195f39885 +bc348767e2dd285ca15 4 1] +49:37.771884127 INFO TestTutorialInvokeSC.ch1 solo/run.go:156 state transition --> #4. Requests in the block: 1. Outputs: 1 +``` + +## Off-ledger Requests + +Alternatively, you could send an off-ledger request by using `chain.PostRequestOffLedger` instead of `PostRequestSync`. +However, since off-ledger requests cannot have tokens attached, in order to cover the gas fee, you must deposit funds to +the chain beforehand: + +```go +user, _ := env.NewKeyPairWithFunds(env.NewSeedFromIndex(1)) +chain.DepositBaseTokensToL2(10_000, user) // to cover gas fees +_, err = chain.PostRequestOffLedger(req, user) +require.NoError(t, err) +``` diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/test.mdx b/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/test.mdx new file mode 100644 index 00000000000..aedbaab2e19 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/test.mdx @@ -0,0 +1,123 @@ +--- +tags: + - testing + - solo testing environment + - call context + - smart contract functionalities + - data types + - type conversions + - Go + +description: Testing of smart contracts happens in the Solo testing environment. This enables synchronous, deterministic testing of smart contract functionality without the overhead of having to start nodes, set up a committee, and send transactions over the _Tangle_. +image: /img/logo/WASP_logo_dark.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Testing Smart Contracts + +Testing of smart contracts happens in the [Solo](../getting-started.md) testing +environment. This enables synchronous, deterministic testing of smart contract +functionalities without the overhead of having to start nodes, set up a committee, and +send transactions over the _Tangle_. Instead, you can use Go's built-in test environment in +combination with Solo to deploy chains and smart contracts and simulate transactions. + +Solo directly interacts with the ISC code, and therfore uses all the ISC-specific data +types directly. Our Wasm smart contracts cannot access these types directly, because they +run in a separate, sandboxed environment. Therefore, WasmLib implements its +[own versions](../../reference/wasm-lib-data-types.mdx) of these data types, and the _VM_ layer acts as a data type +translator between both systems. + +The impact of this type transformation used to be that to be able to write tests in the +solo environment the user also needed to know about the ISC-specific data types and type +conversion functions, and exactly how to properly pass such data in and out of smart +contract function calls. This burdened the user with an unnecessary increased learning +curve and countless unnecessary type conversions. + +With the introduction of the [Schema Tool](../../schema/how-tos/usage.mdx), we were able to remove this +impedance mismatch and allow the users to test smart contract functionality in terms of +the WasmLib data types and functions that they are already familiar with. To that end, we +introduced `SoloContext`, a new [Call Context](../../explanations/context.mdx) that specifically works with +the Solo testing environment. We aimed to simplify the testing of smart contracts as much +as possible, keeping the full Solo interface hidden as much as possible, but still +available when necessary. + +The only concession we still have to make is to the language used. Because Solo only works +in the Go language environment, we have to use the Go language version of the interface +code that the [Schema Tool](../../schema/how-tos/usage.mdx) generates when testing our smart contracts. Because +WasmLib programming for Go, Rust, and TypeScript are practically identical, we feel that +this is not unsurmountable. The WasmLib interfaces only differ slightly if language +idiosyncrasies force differences in syntax or naming conventions. This hurdle used to be a +lot bigger, when direct programming of Solo had to be used, and most type conversions had +to be done manually. Now we get to use the generated compile-time type-checked interface +to our smart contract functions that we are already familiar with. + +Let's look at the simplest way of initializing a smart contract by using the new +`SoloContext` in a test function: + + + + + +```go +func TestDeploy(t *testing.T) { + ctx := wasmsolo.NewSoloContext(t, dividend.ScName, dividend.OnDispatch) + require.NoError(t, ctx.ContractExists(dividend.ScName)) +} +``` + + + + +The first line will automatically create a new chain, and upload and deploy the provided +example `dividend` contract to this chain. It returns a `SoloContext` for further use. The +second line verifies the existence of the deployed contract on the chain associated with +that [Call Context](../../explanations/context.mdx). + +Here is another part of the `dividend` test code, where you can see how we wrap repetitive +calls to smart contract functions that are used in multiple tests: + + + + + +```go +func dividendMember(ctx *wasmsolo.SoloContext, agent *wasmsolo.SoloAgent, factor uint64) { + member := dividend.ScFuncs.Member(ctx) + member.Params.Address().SetValue(agent.ScAgentID().Address()) + member.Params.Factor().SetValue(factor) + member.Func.Post() +} + +func dividendDivide(ctx *wasmsolo.SoloContext, amount uint64) { + divide := dividend.ScFuncs.Divide(ctx) + divide.Func.TransferBaseTokens(amount).Post() +} + +func dividendGetFactor(ctx *wasmsolo.SoloContext, member *wasmsolo.SoloAgent) uint64 { + getFactor := dividend.ScFuncs.GetFactor(ctx) + getFactor.Params.Address().SetValue(member.ScAgentID().Address()) + getFactor.Func.Call() + value := getFactor.Results.Factor().Value() + return value +} +``` + + + + +As you can see, we pass the `SoloContext` and the parameters to the wrapper functions, +then use the `SoloContext` to create a [Function Descriptor](../../schema/how-tos/funcdesc.mdx) for the wrapped +function, pass any parameters through the [Params](../../schema/how-tos/params.mdx) proxy, and then either +[`post()`](../../schema/how-tos/post.mdx) the function request or [`call`](../../schema/how-tos/call.mdx) the function. Any +results returned are extracted through the descriptor's [Results](../../schema/how-tos/results.mdx) proxy, and +returned by the wrapper function. + +There is hardly any difference in the way the function interface is used within Wasm code +or within Solo test code. The [Call Context](../../explanations/context.mdx) knows how to properly +[`call()`](../../schema/how-tos/call.mdx) or [`post()`](../../schema/how-tos/post.mdx) the function call through the function +descriptor. This makes for seamless testing of smart contracts. + +In the [next section](examples.mdx) we will go deeper into how the helper member functions +of the SoloContext are used to simplify tests. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/the-l1-ledger.md b/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/the-l1-ledger.md new file mode 100644 index 00000000000..ed3c5b84c53 --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/the-l1-ledger.md @@ -0,0 +1,71 @@ +--- +description: How to interact with the L1 ledger in Solo. +image: /img/logo/WASP_logo_dark.png +tags: + - testing + - solo + - UTXO + - tokens + - ledger + - l1 + - how-tos +--- + +# The L1 Ledger + +IOTA Smart Contracts work as a **layer 2** (**L2**) extension of the _IOTA Multi-Asset Ledger_, **layer 1** (**L1**). +The specifics of the ledger is outside the scope of this documentation; for now it is sufficient to know that the ledger +contains balances of different kinds of assets (base tokens, native tokens, foundries and _NFT_s) locked in addresses. +Assets can only be moved on the ledger by unlocking the corresponding address with its private key. + +For example: + +```log +Address: iota1pr7vescn4nqc9lpvv37unzryqc43vw5wuf2zx8tlq2wud0369hjjugg54mf + IOTA: 4012720 + Native token 0x08fcccc313acc182fc2c647dc98864062b163a8ee254231d7f029dc6be3a2de52e0100000000: 100 + NFT 0x94cd51b79d9608ed6e38780d48e9fc8c295b893077739b28ce591c45b33dec44 +``` + +In this example, the address owns some base tokens (IOTA), 100 units of a native token with ID `0x08fc...`, and an NFT +with ID `0x94cd...`. + +You can find more information about the ledger in the +[Multi-Asset Ledger TIP](https://github.com/lzpap/tips/blob/master/tips/TIP-0018/tip-0018.md). + +In normal operation, the L2 state is maintained by a committee of Wasp _nodes_. The L1 ledger is provided and +maintained by a network of [Hornet](https://github.com/iotaledger/hornet) nodes, which is a distributed implementation +of the IOTA Multi-Asset Ledger. + +The Solo environment implements a standalone in-memory ledger, simulating the behavior of a real L1 ledger without the +need to run a network of Hornet nodes. + +The following example creates a new wallet (private/public key pair) and requests some base tokens from the faucet: + +```go +func TestTutorialL1(t *testing.T) { + env := solo.New(t) + _, userAddress := env.NewKeyPairWithFunds(env.NewSeedFromIndex(1)) + t.Logf("address of the user is: %s", userAddress.Bech32(parameters.L1.Protocol.Bech32HRP)) + numBaseTokens := env.L1BaseTokens(userAddress) + t.Logf("balance of the user is: %d base tokens", numBaseTokens) + env.AssertL1BaseTokens(userAddress, utxodb.FundsFromFaucetAmount) +} +``` + +The _output_ of the test is: + +```log +=== RUN TestTutorialL1 +47:49.136622566 INFO TestTutorialL1.db dbmanager/dbmanager.go:64 creating new in-memory database for: CHAIN_REGISTRY +47:49.136781104 INFO TestTutorialL1 solo/solo.go:162 Solo environment has been created: logical time: 00:01.001000000, time step: 1ms + tutorial_test.go:32: address of the user is: tgl1qp5d8zm9rr9rcae2hq95plx0rquy5gu2mpedurm2kze238neuhh5csjngz0 + tutorial_test.go:34: balance of the user is: 1000000000 base tokens +--- PASS: TestTutorialL1 (0.00s) +``` + +The L1 ledger in Solo can be accessed via the Solo instance called `env`. +The ledger is unique for the lifetime of the Solo environment. +Even if several L2 chains are deployed during the test, all of them will live on the same L1 ledger; this way Solo makes +it possible to test cross-chain transactions. +(Note that in the test above we did not deploy any chains: the L1 ledger exists independently of any chains.) diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/the-l2-ledger.md b/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/the-l2-ledger.md new file mode 100644 index 00000000000..ed737dbeaed --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/the-l2-ledger.md @@ -0,0 +1,176 @@ +--- +description: 'Smart contracts can exchange assets between themselves on the same chain and between different chains, as +well as with addresses on the L1 ledger.' +image: /img/logo/WASP_logo_dark.png +tags: + +- testing +- solo +- account +- address +- wallet +- balances +- ledger + +--- + +# The L2 Ledger + +Each chain in IOTA Smart Contracts contains its own L2 ledger, independent of the L1 ledger. +Smart contracts can exchange assets between themselves on the same chain, between different chains, and with addresses +on the L1 Ledger. + +Imagine that you have a wallet with some tokens on the L1 ledger, and you want to send those tokens to a smart contract +on a chain and later receive these tokens back on L1. + +On the L1 ledger, your wallet's private key is represented by an address, which holds some tokens. +Those tokens are _controlled_ by the private key. + +In IOTA Smart Contracts the L2 ledger is a collection of _on-chain accounts_ (sometimes also called just _accounts_). +Each L2 account is controlled by the same private key as its associated address and can hold tokens on the chain's +ledger, just like an address can hold tokens on L1. +This way, the chain is essentially a custodian of the tokens deposited in its accounts. + +## Deposit and Withdraw Tokens + +The following test demonstrates how a wallet can deposit tokens in a chain +account and then withdraw them. + +Note that the math is made somewhat more complex by the gas fees and storage deposit. +You could ignore them, but we include them in the example to show you exactly how you can handle them. + +```go +func TestTutorialAccounts(t *testing.T) { + env := solo.New(t, &solo.InitOptions{AutoAdjustStorageDeposit: true}) + chain := env.NewChain() + + // create a wallet with some base tokens on L1: + userWallet, userAddress := env.NewKeyPairWithFunds(env.NewSeedFromIndex(0)) + env.AssertL1BaseTokens(userAddress, utxodb.FundsFromFaucetAmount) + + // the wallet can we identified on L2 by an AgentID: + userAgentID := isc.NewAgentID(userAddress) + // for now our on-chain account is empty: + chain.AssertL2BaseTokens(userAgentID, 0) + + // send 1 Mi from the L1 wallet to own account on-chain, controlled by the same wallet + req := solo.NewCallParams(accounts.Contract.Name, accounts.FuncDeposit.Name). + AddBaseTokens(1 * isc.Million) + + // estimate the gas fee and storage deposit + gas1, gasFee1, err := chain.EstimateGasOnLedger(req, userWallet, true) + require.NoError(t, err) + storageDeposit1 := chain.EstimateNeededStorageDeposit(req, userWallet) + require.Zero(t, storageDeposit1) // since 1 Mi is enough + + // send the deposit request + req.WithGasBudget(gas1). + AddBaseTokens(gasFee1) // including base tokens for gas fee + _, err = chain.PostRequestSync(req, userWallet) + require.NoError(t, err) + + // our L1 balance is 1 Mi + gas fee short + env.AssertL1BaseTokens(userAddress, utxodb.FundsFromFaucetAmount-1*isc.Million-gasFee1) + // our L2 balance is 1 Mi + chain.AssertL2BaseTokens(userAgentID, 1*isc.Million) + // (the gas fee went to the chain's private account) + + // withdraw all base tokens back to L1 + req = solo.NewCallParams(accounts.Contract.Name, accounts.FuncWithdraw.Name). + WithAllowance(isc.NewAssetsBaseTokens(1 * isc.Million)) + + // estimate the gas fee and storage deposit + gas2, gasFee2, err := chain.EstimateGasOnLedger(req, userWallet, true) + require.NoError(t, err) + storageDeposit2 := chain.EstimateNeededStorageDeposit(req, userWallet) + + // send the withdraw request + req.WithGasBudget(gas2). + AddBaseTokens(gasFee2 + storageDeposit2). // including base tokens for gas fee and storage + AddAllowanceBaseTokens(storageDeposit2) // and withdrawing the storage as well + _, err = chain.PostRequestSync(req, userWallet) + require.NoError(t, err) + + // we are back to the initial situation, having been charged some gas fees + // in the process: + env.AssertL1BaseTokens(userAddress, utxodb.FundsFromFaucetAmount-gasFee1-gasFee2) + chain.AssertL2BaseTokens(userAgentID, 0) +} +``` + +The example above creates a chain and a wallet with `utxodb.FundsFromFaucetAmount` base tokens on L1. +Then, it sends 1 million tokens to the corresponding on-chain account by posting a +[`deposit`](../../reference/core-contracts/accounts.md#deposit) request to the +[`accounts` core contract](../../reference/core-contracts/accounts.md) on the chain. + +Finally, it sends a [`withdraw`](../../reference/core-contracts/accounts.md#withdraw) request to the `accounts` core +contract to get the tokens back to L1. + +Both requests are affected by the gas fees and the storage deposit. +In some cases, it is possible to ignore these amounts if they are negligible compared to the transferred amounts. +In this case, however, we want to be very precise. + +### Deposit Requests + +#### 1. Request to Deposit Funds + +The first step in the deposit request is to create a request to deposit the funds with `solo.NewCallParams`. + +#### 2. Add Base Tokens + +In the example above we want to deposit 1 Mi, so we call `AddBaseTokens(1 * isc.Million)`. + +This instructs Solo to take that amount from the L1 balance and add it to the transaction. This is only possible for +on-ledger requests. + +#### 3. Calculate Gas Fees + +Once the chain executes the request, it will be charged a gas fee. + +We use `chain.EstimateGasOnLedger` before actually sending the request to estimate this fee. + +#### 4. Estimate Storage Deposit + +On-ledger requests also require a storage deposit. We use `EstimateNeededStorageDeposit` for this. As the 1 Mi already +included is enough for the storage deposit there’s no need to add more. + +#### 5. Add Gas Budget to the Request + +We adjust the request with the gas budget and the gas fee with `WithGasBudget` and `AddBaseTokens`, respectively. + +#### 6. Send the On-Ledger Request + +Finally, we send the on-ledger request with `PostRequestSync`. + +#### 7. The Chain Picks Up the Request + +Any attached base tokens (1 Mi + gas fee) are automatically credited to the sender's L2 account. + +#### 8. The chain executes the request + +The gas fee is deducted from the sender's L2 account. + +#### 9. The Transfer is Complete + +We have exactly 1 Mi on our L2 balance. + +### Withdraw Request + +The process for the `withdraw` request is similar to the [deposit process](#deposit-requests), with two main +differences: + +#### 1. Ensure the L1 Transaction Can Cover the Storage Deposit + +As the storage deposit is larger than the gas fee, we must ensure that the L1 transaction contains enough funds for the +storage deposit. These tokens are automatically deposited in our L2 account, and we immediately withdraw them. + +#### 2.Set the Request's Allowance + +We use `AddAllowanceBaseTokens` to set the _allowance_ of our request. The allowance specifies the maximum amount of +tokens the smart contract can debit from the sender's L2 account. + +It would fail if we posted the same `deposit` request from another user wallet (another private key). +Try it! Only the address owner can move those funds from the on-chain account. + +You can also try removing the `AddAllowanceBaseTokens` call. It will fail because a smart contract cannot deduct funds from the +sender's L2 balance unless explicitly authorized by the allowance. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/timelock.mdx b/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/timelock.mdx new file mode 100644 index 00000000000..d30cfade07b --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/timelock.mdx @@ -0,0 +1,131 @@ +--- +tags: + - testing + - colored tokens + - time locks + - solo + - plain iotas + - balance + - mint + - delay + +description: You can post a time-locked request by using the Delay() method. You can mint NFTs by using the MintNFT() method. +image: /img/logo/WASP_logo_dark.png +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Minting NFTs and Time Locks + +Let's examine some less commonly used member functions of the SoloContext. We will switch +to the `fairauction` example to show their usage. Here is the `startAuction()` function of +the `fairauction` test suite: + + + + + +```go +const ( + description = "Cool NFTs for sale!" + deposit = uint64(1000) + minBid = uint64(500) +) + +func startAuction(t *testing.T) (*wasmsolo.SoloContext, *wasmsolo.SoloAgent, wasmtypes.ScNftID) { + ctx := wasmsolo.NewSoloContext(t, fairauction.ScName, fairauction.OnDispatch) + auctioneer := ctx.NewSoloAgent() + nftID := ctx.MintNFT(auctioneer, []byte("NFT metadata")) + require.NoError(t, ctx.Err) + + // start the auction + sa := fairauction.ScFuncs.StartAuction(ctx.Sign(auctioneer)) + sa.Params.MinimumBid().SetValue(minBid) + sa.Params.Description().SetValue(description) + transfer := wasmlib.NewScTransferBaseTokens(deposit) // deposit, must be >=minimum*margin + transfer.AddNFT(&nftID) + sa.Func.Transfer(transfer).Post() + require.NoError(t, ctx.Err) + + return ctx, auctioneer, nftID +} +``` + + + + +The function first sets up the SoloContext as usual, and then it performs quite a bit of +extra work. This is because we want the startAuction() function to start an auction, so +that the tests that subsequently use startAuction() can then focus on testing all kinds of +bidding and auction results. + +First, we are going to need an agent that functions as the `auctioneer`. This auctioneer +will auction off an NFT. To provide the auctioneer with this NFT we use the `MintNFT()` +method to mint a fresh NFT into his account. The minting process will assign a unique NFT +ID. Of course, we check that no error occurred during the minting process. + +Now we are going to start the auction by calling the `startAuction` function of the +`fairauction` contract. We get the function descriptor in the usual way, but we also call +the `Sign()` method of the SoloContext to make sure that the transaction we are about to +post takes its assets from the auctioneer address, and the transaction will be signed with +the corresponding private key. Very often you won't care who posts a request, and we have +set it up in such a way that by default tokens come from the chain originator address, +which has been seeded with tokens just for this occasion. But whenever it is important +where the tokens come from, or who invokes the request, you need to specify the agent +involved by using the Sign() method. + +Next we set up the function parameters as usual. After the parameters have been set up, we +see something new happening. We create an `ScTransfer` proxy and initialize it with the +base tokens that we need to deposit, plus the freshly minted NFT that we are auctioning. +Next we use the `Transfer()` method to pass this proxy before posting the request. This is +exactly how we would do it from within the smart contract code. Note that the function +`NewScTransferBaseTokens()` is used as a shorthand to immediately initialize the new +`ScTransfer` proxy with the desired amount of base tokens. + +Finally, we make sure there was no error after posting the request and return the +SoloContext, `auctioneer` and `nftID`. That concludes the startAuction() function. + +Here is the first test function that uses our startAuction() function: + + + + + +```go +func TestStartAuction(t *testing.T) { + ctx, auctioneer, nftID := startAuction(t) + + nfts := ctx.Chain.L2NFTs(auctioneer.AgentID()) + require.Len(t, nfts, 0) + nfts = ctx.Chain.L2NFTs(ctx.Account().AgentID()) + require.Len(t, nfts, 1) + require.Equal(t, nftID, ctx.Cvt.ScNftID(&nfts[0])) + + // remove pending finalize_auction from backlog + ctx.AdvanceClockBy(61 * time.Minute) + require.True(t, ctx.WaitForPendingRequests(1)) +} +``` + + + + +This test function checks that the NFT was moved by `startAuction` from the auctioneer's +on-chain account to the chain's on-chain account. + +The `startAuction` function of the smart contract will also have posted a time-locked +request to the `finalizeAuction` function by using the `Delay()` method. Therefore, we +need to remove the pending `finalizeAuction` request from the backlog. + +First we move the logical clock forward to a point in time when that request is supposed +to have been triggered. Then we wait for this request to actually be processed. Note that +this will happen in a separate goroutine in the background, so we explicitly wait for the +request counters to catch up with the one request that is pending. + +The `WaitForPendingRequests()` method can also be used whenever a smart contract function +is known to [`post()`](../../schema/how-tos/post.mdx) a request to itself. Such requests are not immediately +executed, but added to the backlog, so you need to wait for these pending requests to +actually be processed. The advantage of having to explicitly wait for those requests is +that you can inspect the in-between state, which means that you can test even a function +that posts a request in isolation. diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/view-sc.md b/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/view-sc.md new file mode 100644 index 00000000000..2bac649b39e --- /dev/null +++ b/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/view-sc.md @@ -0,0 +1,74 @@ +--- +description: Calling smart contract view functions with Solo. +image: /img/tutorial/call_view.png +tags: + - how to + - testing + - solo + - views + - call + - synchronous + - entry points +--- + +# Calling a View + +The following snippet shows how you can call the view function `getString` of the smart contract `solotutorial` without +parameters: + +```go +res, err := chain.CallView("example1", "getString") +``` + +The call returns a collection of key/value pairs `res` and an error result `err` in the typical Go fashion. + +[![Calling a view process](/img/tutorial/call_view.png)](/img/tutorial/call_view.png) + +The basic principle of calling a view is similar to sending a request to the smart contract. The essential difference is +that calling a view does not constitute an asynchronous transaction; it is just a direct synchronous call to the view +entry point exposed by the smart contract. + +Therefore, calling a view does not involve any token transfers. Sending a request (either on-ledger or off-ledger) to a +view entry point will result in an exception, returning all attached tokens to the sender minus fees (iif any). + +Views are used to retrieve information about the smart contract's state, for example, to display on a website. Certain +Solo methods such as `chain.GetInfo`, `chain.GetGasFeePolicy`, and `chain.L2Assets` call views of +the [core smart contracts](../../reference/core-contracts/overview.md) behind the scenes to retrieve the information +about the chain or a specific smart contract. + +## Decoding Results Returned by _PostRequestSync_ and _CallView_ + +The following is a specific technicality of the Go environment of _Solo_. + +The result returned by the call to an entry point from the Solo environment is an instance of +the [`dict.Dict`](https://github.com/iotaledger/wasp/blob/develop/packages/kv/dict/dict.go) type, which is essentially a +map of `[]byte` key/value pairs, defined as: + +```go +type Dict map[kv.Key][]byte +``` + +`Dict` is also an implementation of +the [`kv.KVStore`](https://github.com/iotaledger/wasp/blob/develop/packages/kv/kv.go) interface. The `kv` package and +subpackages provide many useful functions to work with the `Dict` type. + +:::note + +Both view and non-view entry points can produce results. +In normal operation, retrieving the result of an on-ledger request is impossible since it is an asynchronous operation. + +However, in the Solo environment, the call to `PostRequestSync` is synchronous, allowing the caller to inspect the +result. +This is a convenient difference between the mocked Solo environment and the distributed ledger used by Wasp nodes. +You can use it to make assertions about the results of a call in the tests. + +::: + +In the example above, `res` is a dictionary where keys and values are binary slices. The `getString` view returns the +value under the `"str"` key, and the value is a `string` encoded as a byte slice. The `codec` package provides functions +to encode/decode frequently used data types, including `string`. The following is a commonly used pattern to get a value +from the `Dict` and decode it: + +```go +var value string = codec.MustDecodeString(res["str"]) +``` diff --git a/docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/chain-management.md b/docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/chain-management.md new file mode 100644 index 00000000000..b6273d1dd93 --- /dev/null +++ b/docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/chain-management.md @@ -0,0 +1,74 @@ +--- +description: 'How to manage a chain using the Grafana dashboard, a client to receive published events, logging, and +validators.' +image: /img/logo/WASP_logo_dark.png +tags: + + - Smart Contracts + - Chain + - Management + - Grafana + +--- + +# Manage a Chain + +## Monitoring + +You can view the chain state using the dashboard (`/wasp/dashboard` when using `node-docker-setup`). + +## Manage Chain Configuration and Validators + +You can manage the chain configuration and committee of validators by interacting with +the [Governance contract](/isc/reference/core-contracts/governance). + +The “Chain Owner” is the only one who can perform administrative tasks. + +### Change Chain Ownership + +To change the chain ownership, the current “Chain Owner” must call `delegateChainOwnership` specifying the `agentID` of +the next owner. The next owner must call `claimChainOwnership` to finalize the process. + +### Change Access Nodes + +For new access nodes to join the network, they need to: + +- Be added as a trusted peer to at least 1 of the existing nodes. +- Be added by the administrator to the list of access nodes by calling `changeAccessNodes`. There is a helper in + wasp-cli to do so: + +```shell +wasp-cli chain gov-change-access-nodes accept +``` + +After this, new nodes should be able to sync the state and execute view queries (call view entry points). + +You can remove an access node by calling `changeAccessNodes`. + +Alternatively, you can add "non-permissioned" access nodes without the signature from the chain owner to add any node as an "access node". +You can do this by using the following command: + +```shell +wasp-cli chain access-nodes +``` + +This node won't be "officially" recognized by the committee but will still be able to sync the state and provide all regular functionality. + +### Change the Set of Validators + +You can do this in different ways, depending on who controls the [governor address](/tips/tips/TIP-0018#alias-output) +from the alias output of the chain. + +- If the chain governor address is the chain committee, you can perform the rotation by calling + `rotateStateController` after adding the next state controller via `addAllowedStateControllerAddress`. +- If the chain governor address is a regular user wallet that you control, you can issue the rotation transaction using wasp-cli: + +```shell +wasp-cli chain rotate +``` + +Or: + +```shell +wasp-cli chain rotate-with-dkg --peers=<...> +``` diff --git a/docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/running-a-node.md b/docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/running-a-node.md new file mode 100644 index 00000000000..79b1f5040f2 --- /dev/null +++ b/docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/running-a-node.md @@ -0,0 +1,34 @@ +--- +description: How to run a node. Requirements, configuration parameters, dashboard configuration, and tests. +image: /img/logo/WASP_logo_dark.png +tags: + - Smart Contracts + - Running a node + - Go-lang + - Hornet + - Requirements + - Configuration + - Dashboard + - Grafana + - Prometheus +--- + +# Running a Node + +As Wasp is an INX plugin, you must run the wasp node alongside your _hornet node_. You can use the simple docker-compose setup to do so. + +## Recommended Hardware Requirements + +We recommend that you run the docker image on a server with: + +* **CPU**: 8 core. +* **RAM**: 16 GB. +* **Disk space**: ~ 250 GB SSD, depending on your pruning configuration. + +## Set Up + +Clone and follow the instructions on the [node-docker-setup repo](https://github.com/iotaledger/node-docker-setup). + +:::note +This is aimed at production-ready deployment. If you're looking to spawn a local node for testing/development, please see the [local-setup](https://github.com/iotaledger/wasp/tree/develop/tools/local-setup) +::: diff --git a/docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/running-an-access-node.md b/docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/running-an-access-node.md new file mode 100644 index 00000000000..a12240bda0a --- /dev/null +++ b/docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/running-an-access-node.md @@ -0,0 +1,283 @@ +--- +description: How to setup an access node. +image: /img/logo/WASP_logo_dark.png +tags: + - Smart Contracts + - Running a node + - ISC +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Running an ISC Access Node + +## Set Up Wasp and Hornet + +First, you should [set up a Wasp Node](./running-a-node.md) but don't run `docker compose up` to start the docker containers yet. Continue with the following steps first: + +### Download the Chain State + +You can configure how much of the state you wish to keep on your node by uncommenting and changing the `WASP_PRUNING_MIN_STATES_TO_KEEP` environment variable in the node-docker-setup. The default value is 10000 blocks. + +### Run a Non-archive Node + +If you wish to run a non-archive node (only keep the last N blocks), you must uncomment `WASP_SNAPSHOT_NETWORK_PATHS`. + +### Run An Archive Node + +If you wish to have a full archive node, you need to set `WASP_PRUNING_MIN_STATES_TO_KEEP` to `0` and comment `WASP_SNAPSHOT_NETWORK_PATHS` out. + +You can then download the historical state using the following command (this will take a while): + + + + + +```sh +wget https://files.stardust-mainnet.iotaledger.net/dbs/wasp/latest-wasp_chains_wal.tgz -O - | tar xzv -C data/wasp +``` + + + + +```sh +wget https://files.iota-testnet.iotaledger.net/dbs/wasp/latest-wasp_chains_wal.tgz -O - | tar xzv -C data/wasp +``` + + + + +```sh +wget https://files.shimmer.network/dbs/wasp/latest-wasp_chains_wal.tgz -O - | tar xzv -C data/wasp +``` + + + + +```sh +wget https://files.testnet.shimmer.network/dbs/wasp/latest-wasp_chains_wal.tgz -O - | tar xzv -C data/wasp +``` + + + + +:::note Disk Space + +Operating as a full archive node requires a lot of disk space. We recommend at least 500Gb of free space to operate without issues + +::: + +### Run Everything + +```sh +docker compose up -d +``` + +It will take a few minutes until the hornet node is synced. + +You can check the sync status by following the logs with `docker logs -f hornet`, or in the web dashboard. + +## Use Wasp-Cli to configure the chain and add peers +### Download Wasp-Cli + +You can download a Wasp-Cli that matches your Wasp version from the [Wasp releases](https://github.com/iotaledger/wasp/releases). +You can use a commands like the following to for example download version 1.1.0: + +```sh +curl -sL https://github.com/iotaledger/wasp/releases/download/v1.1.0/wasp-cli_1.1.0_Linux_x86_64.tar.gz | tar xzv +``` + +Change directory into the newly-downloaded `wasp-cli` directory: + +```sh +cd wasp-cli_1.1.0_Linux_x86_64/ +``` + +### Set the L1 API Address + +Set the L1 API address. You can set it to what you configured as `NODE_HOST` in the `.env` file + +:::tip HTTP + +If you use the http setup, don't forget to replace `https` with `http` + +::: + +```sh +./wasp-cli set l1.apiaddress https://{NODE_HOST} +``` + +### Set Wasp API Address + +Set the WASP API address. It is your configured `NODE_HOST` and the `/wasp/api` path. + +```sh +./wasp-cli wasp add my-node https://{NODE_HOST}/wasp/api +``` + +### Login + +Login to wasp using your credentials. You can update your current credentials or add new ones in the wasp dashboard. + +```sh +./wasp-cli login +``` +```sh title=Output +Username: wasp +Password: (default is wasp) +Successfully authenticated +``` + +### Obtain Peering Info + +Get your peering info which you will need to share with your peers: + +```sh +./wasp-cli peering info +``` +```sh title=Output +PubKey: 0x20a56daa0b5e86b196c37f802089a2b6007a655a12337d287f7313a214af2ec0 +PeeringURL: 0.0.0.0:4000 +``` + +Please note the PubKey: 0x20a56daa0b5e86b196c37f802089a2b6007a655a12337d287f7313a214af2ec0 output. +Send it together with your domain/IP to node operators that you want to peer with. + +### Wait for the other party to peer + +Wait until peer added you as trusted and access peer. + +### Use wasp-cli to add nodes as peers + +Now you can add your peer as trusted peer. + +```sh +./wasp-cli peering trust peer1 : +./wasp-cli peering trust peer2 : +``` + +### Add Chain + +Add the chain with its chain id and name: + + + + +```sh +./wasp-cli chain add iota-evm iota1pzt3mstq6khgc3tl0mwuzk3eqddkryqnpdxmk4nr25re2466uxwm28qqxu5 +``` + + + + +```sh +./wasp-cli chain add iota-evm-testnet tst1pzxsrr7apqkdzz633dyntmvxwtyvk029p39te5j0m33q6946h7akzv663zu +``` + + + + +```sh +./wasp-cli chain add shimmer-evm smr1prxvwqvwf7nru5q5xvh5thwg54zsm2y4wfnk6yk56hj3exxkg92mx20wl3s +``` + + + + +```sh +./wasp-cli chain add shimmer-evm-testnet rms1ppp00k5mmd2m8my8ukkp58nd3rskw6rx8l09aj35984k74uuc5u2cywn3ex +``` + + + + +### Activate + +Activate the chain using its name: + + + + + +```sh +./wasp-cli chain activate --chain iota-evm +``` + + + + +```sh +./wasp-cli chain activate --chain iota-evm-testnet +``` + + + + +```sh +./wasp-cli chain activate --chain shimmer-evm +``` + + + + +```sh +./wasp-cli chain activate --chain shimmer-evm-testnet +``` + + + + +### Add Peers as Access Nodes of the Chain + +Add the peers as access nodes. + +:::info + +This is normally only needed for peers that you plan to add as access nodes to your own node + +::: + +```sh +./wasp-cli chain access-nodes add --peers=peer1,peer2 +``` + +### Check if Wasp Synced + +You can follow the progress using `docker logs -f wasp`. If you chose to create a [full-archive node](#run-and-archive-node), this can take several minutes, maybe hours. + +### Test Your Endpoint + +You should have a working EVM JSON-RPC endpoint on: + + + + +``` +/wasp/api/v1/chains/iota1pzt3mstq6khgc3tl0mwuzk3eqddkryqnpdxmk4nr25re2466uxwm28qqxu5/evm +``` + + + + +``` +/wasp/api/v1/chains/tst1pzxsrr7apqkdzz633dyntmvxwtyvk029p39te5j0m33q6946h7akzv663zu/evm +``` + + + + + +``` +/wasp/api/v1/chains/smr1prxvwqvwf7nru5q5xvh5thwg54zsm2y4wfnk6yk56hj3exxkg92mx20wl3s/evm +``` + + + + +``` +/wasp/api/v1/chains/rms1ppp00k5mmd2m8my8ukkp58nd3rskw6rx8l09aj35984k74uuc5u2cywn3ex/evm +``` + + + diff --git a/docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/setting-up-a-chain.md b/docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/setting-up-a-chain.md new file mode 100644 index 00000000000..d71c78d5372 --- /dev/null +++ b/docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/setting-up-a-chain.md @@ -0,0 +1,176 @@ +--- +description: 'Setting up a chain: requirements, configuration parameters, validators, and tests.' +image: /img/logo/WASP_logo_dark.png +tags: + - Smart Contracts + - Chain + - Set up + - Configuration + - Nodes + - Tests +--- + +# Set Up a Chain + +:::note + +It is possible to run a "committee" of a single Wasp node, which is okay for testing purposes. + +However, in normal operation, multiple Wasp _nodes_ should be used. + +::: + +## Requirements + +- [`wasp-cli` configured](wasp-cli.md) to interact with your wasp node. + +## Trust Setup + +After starting all the `wasp` nodes, you should make them trust each other. Node operators should do this manually. It's +their responsibility to accept trusted nodes only. + +The operator can read their node's public key and PeeringURL by running `wasp-cli peering info`: + +```shell +wasp-cli peering info +``` + +Example response: + +```log +PubKey: 8oQ9xHWvfnShRxB22avvjbMyAumZ7EXKujuthqrzapNM +PeeringURL: 127.0.0.1:4000 +``` + +You should provide your `PubKey` and `PeeringURL` to other node operators. +They can use this info to trust and accept communications with your node. +That's done by invoking `wasp-cli peering trust `, e.g.: + +```shell +wasp-cli peering trust another-node 8oQ9xHWvfnShRxB22avvjbMyAumZ7EXKujuthqrzapNM 127.0.0.1:4000 +``` + +You can view the list of your wasp node's trusted peers by calling: + +```shell +wasp-cli peering list-trusted +``` + +All the nodes in a committee must trust each other to run the chain. + +## Start the Chain + +### Request Test Funds (only for Testnet) + +You can request test funds to safely develop your application by calling: + +```shell +wasp-cli request-funds +``` + +### Deploy the IOTA Smart Contracts Chain + +You can deploy your IOTA Smart Contracts chain by running: + +```shell +wasp-cli chain deploy --peers=foo,bar,baz --chain=mychain --block-keep-amount=10000 +``` + +The names in `--peers=foo,bar,baz` correspond to the names of the node's trusted peers. + +The `--chain=mychain` flag sets up an alias for the chain. +From now on, all chain commands will target this chain. + +The `--quorum` flag indicates the minimum number of nodes required to form a _consensus_. +The recommended formula to obtain this number is `floor(N*2/3)+1` where `N` is the number of nodes in your committee. + +The `--block-keep-amount` parameter determines how many blocks are stored in the [`blocklog`](/isc/reference/core-contracts/blocklog) core contract. + +After deployment, the chain must be activated by the node operators of all peers. + +```shell +wasp-cli chain add # adds the chain to the wasp-cli config, can be skipped on the wasp-cli that initiated the deployment +wasp-cli chain activate --chain= +``` + +## Test If It Works + +You can check that the chain was deployed correctly in the Wasp node dashboard (`/wasp/dashboard` when using `node-docker-setup`). +Note that the chain was deployed with some [core contracts](/isc/reference/core-contracts/overview). + +You should also have an EVM-JSONRPC server opened on: + +```info +/chain//evm +``` + +### Deploying a Wasm Contract + +:::warning +The WASM _VM_ is experimental. However, similar commands can be used to interact with the core contracts +::: + +Now you can deploy a Wasm contract to the chain: + +```shell +wasp-cli chain deploy-contract wasmtime inccounter "inccounter SC" tools/cluster/tests/wasm/inccounter_bg.wasm +``` + +The `inccounter_bg.wasm` file is a precompiled Wasm contract included in the Wasp repo as an example. + +If you recheck the dashboard, you should see that the `inccounter` contract is listed in the chain. + +### Interacting With a Smart Contract + +You can interact with a contract by calling its exposed functions and views. + +For instance, the [`inccounter`](https://github.com/iotaledger/wasp/tree/master/contracts/wasm/inccounter/src) contract +exposes the `increment` function, which simply increments a counter stored in the state. It also has the `getCounter` +view that returns the current value of the counter. + +You can call the `getCounter` view by running: + +```shell +wasp-cli chain call-view inccounter getCounter | wasp-cli decode string counter int +``` + +Example response: + +```log +counter: 0 +``` + +:::note + +The part after `|` is necessary because the return value is encoded, and you need to know the _schema_ to +decode it. **The schema definition is in its early stages and will likely change in the future.** + +::: + +You can now call the `increment` function by running: + +```shell +wasp-cli chain post-request inccounter increment +``` + +After the committee has processed the request, you should get a new +counter value after calling `getCounter`: + +```shell +wasp-cli chain call-view inccounter getCounter | wasp-cli decode string counter int +``` + +Example response: + +```log +counter: 1 +``` + +### Troubleshooting + +Common issues can be caused by using an incompatible version of `wasp` / `wasp-cli`. +You can verify that `wasp-cli` and `wasp` nodes are on the same version by running: + +```shell +wasp-cli check-versions +``` diff --git a/docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/wasp-cli.md b/docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/wasp-cli.md new file mode 100644 index 00000000000..a09445e0aaf --- /dev/null +++ b/docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/wasp-cli.md @@ -0,0 +1,67 @@ +--- +description: How to configure wasp-cli. Requirements and configuration parameters. +image: /img/logo/WASP_logo_dark.png +tags: + - Wasp-cli + - Configuration + - Hornet + - command line +--- + +# Configure wasp-cli + +You can use these step-by-step instructions on how to use wasp-cli to interact with Wasp nodes on the Hornet network. + +## Download wasp-cli + +Download the latest wasp-cli binary from the repo [releases page](https://github.com/iotaledger/wasp/releases). +(For ease of use, it is recommended to add `wasp-cli` to your system `PATH`). + +## Configuration + +You can create a basic default configuration by running: + +```shell +wasp-cli init +``` + +This command will create a configuration file named `wasp-cli.json` in `~/.wasp-cli/wasp-cli.json` (you can change the default with the `-c, --config` flag). + +:::info Wallet Provider + +By default wasp-cli will store the seed in your OS keychain. You can change this behavior by running + +```shell +wasp-cli wallet-provider (keychain, sdk_ledger, sdk_stronghold) [flags] +``` + +::: + +:::info Deprecated Seed storage + +If you use a version older then [1.0.3](https://github.com/iotaledger/wasp/releases/tag/v1.0.3-alpha.1) your seed is still stored as plain text. You can migrate to the keychain by using the following command: + +```shell +wasp-cli wallet-migrate (keychain) [flags] +``` + +::: + +After this, you will need to tell the `wasp-cli` the location of the _Hornet node_ and the committee of Wasp nodes: + +```shell +wasp-cli set l1.apiaddress http://localhost:14265 +# the faucet only exists for test networks +wasp-cli set l1.faucetaddress http://localhost:8091 + +# You can add as many nodes as you'd like +wasp-cli wasp add wasp-0 127.0.0.1:9090 +wasp-cli wasp add wasp-1 127.0.0.1:9091 +``` + +If you configure the Wasp node to use JWT authentication, you will need to log in +after you save the configuration. + +```shell +wasp-cli login +``` diff --git a/docs/content/guides/operator/layer-2-smart-contracts-node/reference/configuration.md b/docs/content/guides/operator/layer-2-smart-contracts-node/reference/configuration.md new file mode 100755 index 00000000000..bfe1181b5b5 --- /dev/null +++ b/docs/content/guides/operator/layer-2-smart-contracts-node/reference/configuration.md @@ -0,0 +1,573 @@ +--- +# !!! DO NOT MODIFY !!! +# This file is auto-generated by the gendoc tool based on the source code of the app. +description: This section describes the configuration parameters and their types for WASP. +tags: + - IOTA Node + - Hornet Node + - WASP Node + - Smart Contracts + - L2 + - Configuration + - JSON + - Customize + - Config + - reference +--- + + +# Core Configuration + +WASP uses a JSON standard format as a config file. If you are unsure about JSON syntax, you can find more information in the [official JSON specs](https://www.json.org). + +You can change the path of the config file by using the `-c` or `--config` argument while executing `wasp` executable. + +For example: +```shell +wasp -c config_defaults.json +``` + +You can always get the most up-to-date description of the config parameters by running: + +```shell +wasp -h --full +``` + +## 1. Application + +| Name | Description | Type | Default value | +| ------------------------- | ------------------------------------------------------ | ------- | ------------- | +| checkForUpdates | Whether to check for updates of the application or not | boolean | true | +| [shutdown](#app_shutdown) | Configuration for shutdown | object | | + +### Shutdown + +| Name | Description | Type | Default value | +| ------------------------ | ------------------------------------------------------------------------------------------------------ | ------ | ------------- | +| stopGracePeriod | The maximum time to wait for background processes to finish during shutdown before terminating the app | string | "5m" | +| [log](#app_shutdown_log) | Configuration for Shutdown Log | object | | + +### Shutdown Log + +| Name | Description | Type | Default value | +| -------- | --------------------------------------------------- | ------- | -------------- | +| enabled | Whether to store self-shutdown events to a log file | boolean | true | +| filePath | The file path to the self-shutdown log | string | "shutdown.log" | + +Example: + +```json + { + "app": { + "checkForUpdates": true, + "shutdown": { + "stopGracePeriod": "5m", + "log": { + "enabled": true, + "filePath": "shutdown.log" + } + } + } + } +``` + +## 2. Logger + +| Name | Description | Type | Default value | +| ---------------------------------------- | --------------------------------------------------------------------------- | ------- | ------------- | +| level | The minimum enabled logging level | string | "info" | +| disableCaller | Stops annotating logs with the calling function's file name and line number | boolean | true | +| disableStacktrace | Disables automatic stacktrace capturing | boolean | false | +| stacktraceLevel | The level stacktraces are captured and above | string | "panic" | +| encoding | The logger's encoding (options: "json", "console") | string | "console" | +| [encodingConfig](#logger_encodingconfig) | Configuration for encodingConfig | object | | +| outputPaths | A list of URLs, file paths or stdout/stderr to write logging output to | array | stdout | +| disableEvents | Prevents log messages from being raced as events | boolean | true | + +### EncodingConfig + +| Name | Description | Type | Default value | +| ----------- | ---------------------------------------------------------------------------------------------------------- | ------ | ------------- | +| timeEncoder | Sets the logger's timestamp encoding. (options: "nanos", "millis", "iso8601", "rfc3339" and "rfc3339nano") | string | "rfc3339" | + +Example: + +```json + { + "logger": { + "level": "info", + "disableCaller": true, + "disableStacktrace": false, + "stacktraceLevel": "panic", + "encoding": "console", + "encodingConfig": { + "timeEncoder": "rfc3339" + }, + "outputPaths": [ + "stdout" + ], + "disableEvents": true + } + } +``` + +## 3. INX + +| Name | Description | Type | Default value | +| --------------------- | -------------------------------------------------------------------------------------------------- | ------ | ---------------- | +| address | The INX address to which to connect to | string | "localhost:9029" | +| maxConnectionAttempts | The amount of times the connection to INX will be attempted before it fails (1 attempt per second) | uint | 30 | +| targetNetworkName | The network name on which the node should operate on (optional) | string | "" | + +Example: + +```json + { + "inx": { + "address": "localhost:9029", + "maxConnectionAttempts": 30, + "targetNetworkName": "" + } + } +``` + +## 4. Cache + +| Name | Description | Type | Default value | +| ------------------ | -------------------------------------- | ------- | ------------- | +| cacheSize | Cache size | string | "64MiB" | +| cacheStatsInterval | Interval for printing cache statistics | string | "30s" | +| enabled | Whether the cache plugin is enabled | boolean | true | + +Example: + +```json + { + "cache": { + "cacheSize": "64MiB", + "cacheStatsInterval": "30s", + "enabled": true + } + } +``` + +## 5. Database + +| Name | Description | Type | Default value | +| ---------------------------- | ---------------------------------------- | ------- | ------------- | +| engine | The used database engine (rocksdb/mapdb) | string | "rocksdb" | +| [chainState](#db_chainstate) | Configuration for chainState | object | | +| debugSkipHealthCheck | Ignore the check for corrupted databases | boolean | true | + +### ChainState + +| Name | Description | Type | Default value | +| --------- | -------------------------------------------- | ------ | -------------------- | +| path | The path to the chain state databases folder | string | "waspdb/chains/data" | +| cacheSize | Size of the RocksDB block cache | uint | 33554432 | + +Example: + +```json + { + "db": { + "engine": "rocksdb", + "chainState": { + "path": "waspdb/chains/data", + "cacheSize": 33554432 + }, + "debugSkipHealthCheck": true + } + } +``` + +## 6. P2p + +| Name | Description | Type | Default value | +| ------------------------- | -------------------------- | ------ | ------------- | +| [identity](#p2p_identity) | Configuration for identity | object | | +| [db](#p2p_db) | Configuration for Database | object | | + +### Identity + +| Name | Description | Type | Default value | +| ---------- | ------------------------------------------------------- | ------ | ------------------------------ | +| privateKey | Private key used to derive the node identity (optional) | string | "" | +| filePath | The path to the node identity PEM file | string | "waspdb/identity/identity.key" | + +### Database + +| Name | Description | Type | Default value | +| ---- | ---------------------------- | ------ | ----------------- | +| path | The path to the p2p database | string | "waspdb/p2pstore" | + +Example: + +```json + { + "p2p": { + "identity": { + "privateKey": "", + "filePath": "waspdb/identity/identity.key" + }, + "db": { + "path": "waspdb/p2pstore" + } + } + } +``` + +## 7. Registries + +| Name | Description | Type | Default value | +| -------------------------------------------- | -------------------------------- | ------ | ------------- | +| [chains](#registries_chains) | Configuration for chains | object | | +| [dkShares](#registries_dkshares) | Configuration for dkShares | object | | +| [trustedPeers](#registries_trustedpeers) | Configuration for trustedPeers | object | | +| [consensusState](#registries_consensusstate) | Configuration for consensusState | object | | + +### Chains + +| Name | Description | Type | Default value | +| -------- | ----------------------------------- | ------ | ----------------------------------- | +| filePath | The path to the chain registry file | string | "waspdb/chains/chain_registry.json" | + +### DkShares + +| Name | Description | Type | Default value | +| ---- | -------------------------------------------------------- | ------ | ----------------- | +| path | The path to the distributed key shares registries folder | string | "waspdb/dkshares" | + +### TrustedPeers + +| Name | Description | Type | Default value | +| -------- | ------------------------------------------- | ------ | --------------------------- | +| filePath | The path to the trusted peers registry file | string | "waspdb/trusted_peers.json" | + +### ConsensusState + +| Name | Description | Type | Default value | +| ---- | ------------------------------------------------- | ------ | ------------------------- | +| path | The path to the consensus state registries folder | string | "waspdb/chains/consensus" | + +Example: + +```json + { + "registries": { + "chains": { + "filePath": "waspdb/chains/chain_registry.json" + }, + "dkShares": { + "path": "waspdb/dkshares" + }, + "trustedPeers": { + "filePath": "waspdb/trusted_peers.json" + }, + "consensusState": { + "path": "waspdb/chains/consensus" + } + } + } +``` + +## 8. Peering + +| Name | Description | Type | Default value | +| ---------- | ---------------------------------------------------- | ------ | -------------- | +| peeringURL | Node host address as it is recognized by other peers | string | "0.0.0.0:4000" | +| port | Port for Wasp committee connection/peering | int | 4000 | + +Example: + +```json + { + "peering": { + "peeringURL": "0.0.0.0:4000", + "port": 4000 + } + } +``` + +## 9. Chains + +| Name | Description | Type | Default value | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------------- | +| broadcastUpToNPeers | Number of peers an offledger request is broadcasted to | int | 2 | +| broadcastInterval | Time between re-broadcast of offledger requests; 0 value means that re-broadcasting is disabled | string | "0s" | +| apiCacheTTL | Time to keep processed offledger requests in api cache | string | "5m" | +| pullMissingRequestsFromCommittee | Whether or not to pull missing requests from other committee members | boolean | true | +| deriveAliasOutputByQuorum | False means we propose own AliasOutput, true - by majority vote. | boolean | true | +| pipeliningLimit | -1 -- infinite, 0 -- disabled, X -- build the chain if there is up to X transactions unconfirmed by L1. | int | -1 | +| postponeRecoveryMilestones | Number of milestones to wait until a chain transition is considered as rejected | int | 3 | +| consensusDelay | Minimal delay between consensus runs. | string | "500ms" | +| recoveryTimeout | Time after which another consensus attempt is made. | string | "20s" | +| redeliveryPeriod | The resend period for msg. | string | "2s" | +| printStatusPeriod | The period to print consensus instance status. | string | "3s" | +| consensusInstsInAdvance | | int | 3 | +| awaitReceiptCleanupEvery | For every this number AwaitReceipt will be cleaned up | int | 100 | +| mempoolTTL | Time that requests are allowed to sit in the mempool without being processed | string | "24h" | +| mempoolMaxOffledgerInPool | Maximum number of off-ledger requests kept in the mempool | int | 2000 | +| mempoolMaxOnledgerInPool | Maximum number of on-ledger requests kept in the mempool | int | 1000 | +| mempoolMaxTimedInPool | Maximum number of timed on-ledger requests kept in the mempool | int | 100 | +| mempoolMaxOffledgerToPropose | Maximum number of off-ledger requests to propose for the next block | int | 500 | +| mempoolMaxOnledgerToPropose | Maximum number of on-ledger requests to propose for the next block (includes timed requests) | int | 100 | +| mempoolOnLedgerRefreshMinInterval | Minimum interval to try to refresh the list of on-ledger requests after some have been dropped from the pool (this interval is introduced to avoid dropping/refreshing cycle if there are too many requests on L1 to process) | string | "10m" | + +Example: + +```json + { + "chains": { + "broadcastUpToNPeers": 2, + "broadcastInterval": "0s", + "apiCacheTTL": "5m", + "pullMissingRequestsFromCommittee": true, + "deriveAliasOutputByQuorum": true, + "pipeliningLimit": -1, + "postponeRecoveryMilestones": 3, + "consensusDelay": "500ms", + "recoveryTimeout": "20s", + "redeliveryPeriod": "2s", + "printStatusPeriod": "3s", + "consensusInstsInAdvance": 3, + "awaitReceiptCleanupEvery": 100, + "mempoolTTL": "24h", + "mempoolMaxOffledgerInPool": 2000, + "mempoolMaxOnledgerInPool": 1000, + "mempoolMaxTimedInPool": 100, + "mempoolMaxOffledgerToPropose": 500, + "mempoolMaxOnledgerToPropose": 100, + "mempoolOnLedgerRefreshMinInterval": "10m" + } + } +``` + +## 10. Snapshots + +| Name | Description | Type | Default value | +| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------------- | +| snapshotsToLoad | List of snapshots to load; can be either single block hash of a snapshot (if a single chain has to be configured) or list of `:` to configure many chains | array | | +| period | How often state snapshots should be made: 1000 meaning "every 1000th state", 0 meaning "making snapshots is disabled" | uint | 0 | +| delay | How many states should pass before snapshot is produced | uint | 20 | +| localPath | The path to the snapshots folder in this node's disk | string | "waspdb/snap" | +| networkPaths | The list of paths to the remote (http(s)) snapshot locations; each of listed locations must contain 'INDEX' file with list of snapshot files | array | | + +Example: + +```json + { + "snapshots": { + "snapshotsToLoad": [], + "period": 0, + "delay": 20, + "localPath": "waspdb/snap", + "networkPaths": [] + } + } +``` + +## 11. StateManager + +| Name | Description | Type | Default value | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------ | ------------- | +| blockCacheMaxSize | How many blocks may be stored in cache before old ones start being deleted | int | 1000 | +| blockCacheBlocksInCacheDuration | How long should the block stay in block cache before being deleted | string | "1h" | +| blockCacheBlockCleaningPeriod | How often should the block cache be cleaned | string | "1m" | +| stateManagerGetBlockNodeCount | How many nodes should get block request be sent to | int | 5 | +| stateManagerGetBlockRetry | How often get block requests should be repeated | string | "3s" | +| stateManagerRequestCleaningPeriod | How often requests waiting for response should be checked for expired context | string | "5m" | +| stateManagerStatusLogPeriod | How often state manager status information should be written to log | string | "1m" | +| stateManagerTimerTickPeriod | How often timer tick fires in state manager | string | "1s" | +| pruningMinStatesToKeep | This number of states will always be available in the store; if 0 - store pruning is disabled | int | 10000 | +| pruningMaxStatesToDelete | On single store pruning attempt at most this number of states will be deleted; NOTE: pruning takes considerable amount of time; setting this parameter large may seriously damage Wasp responsiveness if many blocks require pruning | int | 10 | + +Example: + +```json + { + "stateManager": { + "blockCacheMaxSize": 1000, + "blockCacheBlocksInCacheDuration": "1h", + "blockCacheBlockCleaningPeriod": "1m", + "stateManagerGetBlockNodeCount": 5, + "stateManagerGetBlockRetry": "3s", + "stateManagerRequestCleaningPeriod": "5m", + "stateManagerStatusLogPeriod": "1m", + "stateManagerTimerTickPeriod": "1s", + "pruningMinStatesToKeep": 10000, + "pruningMaxStatesToDelete": 10 + } + } +``` + +## 12. Validator + +| Name | Description | Type | Default value | +| ------- | ------------------------------------------------------------------------------------------------------------------ | ------ | ------------- | +| address | Bech32 encoded address to identify the node (as access node on gov contract and to collect validator fee payments) | string | "" | + +Example: + +```json + { + "validator": { + "address": "" + } + } +``` + +## 13. Write-Ahead Logging + +| Name | Description | Type | Default value | +| ----------- | ---------------------------------------------------------------- | ------- | ------------- | +| loadToStore | Load blocks from "write-ahead log" to the store on node start-up | boolean | false | +| enabled | Whether the "write-ahead logging" is enabled | boolean | true | +| path | The path to the "write-ahead logging" folder | string | "waspdb/wal" | + +Example: + +```json + { + "wal": { + "loadToStore": false, + "enabled": true, + "path": "waspdb/wal" + } + } +``` + +## 14. Web API + +| Name | Description | Type | Default value | +| ------------------------- | ------------------------------------------------------------------------------------------ | ------- | --------------------- | +| enabled | Whether the web api plugin is enabled | boolean | true | +| bindAddress | The bind address for the node web api | string | "0.0.0.0:9090" | +| [auth](#webapi_auth) | Configuration for auth | object | | +| indexDbPath | Directory for storing indexes of historical data (only archive nodes will create/use them) | string | "waspdb/chains/index" | +| [limits](#webapi_limits) | Configuration for limits | object | | +| debugRequestLoggerEnabled | Whether the debug logging for requests should be enabled | boolean | false | + +### Auth + +| Name | Description | Type | Default value | +| ----------------------- | -------------------------------------- | ------ | ------------- | +| scheme | Selects which authentication to choose | string | "jwt" | +| [jwt](#webapi_auth_jwt) | Configuration for JWT Auth | object | | + +### JWT Auth + +| Name | Description | Type | Default value | +| -------- | ------------------ | ------ | ------------- | +| duration | Jwt token lifetime | string | "24h" | + +### Limits + +| Name | Description | Type | Default value | +| --------------------------------- | ----------------------------------------------------------------------------- | ------ | ------------- | +| timeout | The timeout after which a long running operation will be canceled | string | "30s" | +| readTimeout | The read timeout for the HTTP request body | string | "10s" | +| writeTimeout | The write timeout for the HTTP response body | string | "1m" | +| maxBodyLength | The maximum number of characters that the body of an API call may contain | string | "2M" | +| maxTopicSubscriptionsPerClient | Defines the max amount of subscriptions per client. 0 = deactivated (default) | int | 0 | +| confirmedStateLagThreshold | The threshold that define a chain is unsynchronized | uint | 2 | +| [jsonrpc](#webapi_limits_jsonrpc) | Configuration for jsonrpc | object | | + +### Jsonrpc + +| Name | Description | Type | Default value | +| ----------------------------------- | -------------------------------------------------------------- | ------ | ------------- | +| maxBlocksInLogsFilterRange | Maximum amount of blocks in eth_getLogs filter range | int | 1000 | +| maxLogsInResult | Maximum amount of logs in eth_getLogs result | int | 10000 | +| websocketRateLimitMessagesPerSecond | The websocket rate limit (messages per second) | int | 20 | +| websocketRateLimitBurst | The websocket burst limit | int | 5 | +| websocketConnectionCleanupDuration | Defines in which interval stale connections will be cleaned up | string | "5m" | +| websocketClientBlockDuration | The duration a misbehaving client will be blocked | string | "5m" | + +Example: + +```json + { + "webapi": { + "enabled": true, + "bindAddress": "0.0.0.0:9090", + "auth": { + "scheme": "jwt", + "jwt": { + "duration": "24h" + } + }, + "indexDbPath": "waspdb/chains/index", + "limits": { + "timeout": "30s", + "readTimeout": "10s", + "writeTimeout": "1m", + "maxBodyLength": "2M", + "maxTopicSubscriptionsPerClient": 0, + "confirmedStateLagThreshold": 2, + "jsonrpc": { + "maxBlocksInLogsFilterRange": 1000, + "maxLogsInResult": 10000, + "websocketRateLimitMessagesPerSecond": 20, + "websocketRateLimitBurst": 5, + "websocketConnectionCleanupDuration": "5m", + "websocketClientBlockDuration": "5m" + } + }, + "debugRequestLoggerEnabled": false + } + } +``` + +## 15. Profiling + +| Name | Description | Type | Default value | +| ----------- | ------------------------------------------------- | ------- | ---------------- | +| enabled | Whether the profiling component is enabled | boolean | false | +| bindAddress | The bind address on which the profiler listens on | string | "localhost:6060" | + +Example: + +```json + { + "profiling": { + "enabled": false, + "bindAddress": "localhost:6060" + } + } +``` + +## 16. ProfilingRecorder + +| Name | Description | Type | Default value | +| ------- | ----------------------------------------------- | ------- | ------------- | +| enabled | Whether the ProfilingRecorder plugin is enabled | boolean | false | + +Example: + +```json + { + "profilingRecorder": { + "enabled": false + } + } +``` + +## 17. Prometheus + +| Name | Description | Type | Default value | +| ----------- | ------------------------------------------------------------ | ------- | -------------- | +| enabled | Whether the prometheus plugin is enabled | boolean | true | +| bindAddress | The bind address on which the Prometheus exporter listens on | string | "0.0.0.0:2112" | + +Example: + +```json + { + "prometheus": { + "enabled": true, + "bindAddress": "0.0.0.0:2112" + } + } +``` + diff --git a/docs/content/guides/operator/layer-2-smart-contracts-node/reference/metrics.md b/docs/content/guides/operator/layer-2-smart-contracts-node/reference/metrics.md new file mode 100644 index 00000000000..0e816a696e0 --- /dev/null +++ b/docs/content/guides/operator/layer-2-smart-contracts-node/reference/metrics.md @@ -0,0 +1,22 @@ +--- +description: IOTA Smart Contract Protocol is IOTA's solution for running smart contracts on top of the IOTA _tangle_. +image: /img/logo/WASP_logo_dark.png +tags: + - smart contracts + - metrics + - reference +--- + +# Exposed Metrics + +Refer to the [testnet endpoints description](/build/networks-endpoints/#shimmerevm-testnet) for access details. + +| Metric | Description | +| ------------------------------------------ | ---------------------------------------------------- | +| `wasp_off_ledger_requests_counter` | Off-ledger requests per chain. | +| `wasp_on_ledger_request_counter` | On-ledger requests per chain. | +| `wasp_processed_request_counter` | Total number of requests processed. | +| `messages_received_per_chain` | Number of messages received per chain. | +| `receive_requests_acknowledgement_message` | Number of request acknowledgment messages per chain. | +| `request_processing_time` | Time to process request. | +| `vm_run_time` | Time it takes to run the VM. | diff --git a/docs/content/references/layer-2-smart-contracts/.gitignore b/docs/content/references/layer-2-smart-contracts/.gitignore new file mode 100644 index 00000000000..31a1d0913e6 --- /dev/null +++ b/docs/content/references/layer-2-smart-contracts/.gitignore @@ -0,0 +1,3 @@ +magic-contract/* +!magic-contract/introduction.md +iscutils diff --git a/docs/content/references/layer-2-smart-contracts/core-contracts/accounts.md b/docs/content/references/layer-2-smart-contracts/core-contracts/accounts.md new file mode 100644 index 00000000000..18a3f77e787 --- /dev/null +++ b/docs/content/references/layer-2-smart-contracts/core-contracts/accounts.md @@ -0,0 +1,393 @@ +--- +description: 'The `accounts` contract keeps the ledger of on-chain accounts.' +image: /img/logo/WASP_logo_dark.png +tags: + - core contracts + - accounts + - deposit + - withdraw + - assets + - balance + - reference +--- + +# The `accounts` Contract + +The `accounts` contract is one of the [core contracts](overview.md) on each IOTA Smart Contracts +chain. + +This contract keeps a consistent ledger of on-chain accounts in its state, +i.e. [the L2 ledger](../../explanations/how-accounts-work.md). + +--- + +## Entry Points + +The `accounts` contract provides functions to deposit and withdraw tokens, information about the assets deposited on the +chain, and the functionality to create and use foundries. + +### `deposit()` + +A no-op that has the side effect of crediting any transferred tokens to the sender's account. + +:::note Gas Fees + +As with every call, the gas fee is debited from the L2 account right after executing the request. + +::: + +### `withdraw()` + +Moves tokens from the caller's on-chain account to the caller's L1 address. The number of +tokens to be withdrawn must be specified via the allowance of the request. + +:::note Contract Account + +Because contracts does not have a corresponding L1 address it does not make sense to +have them call this function. It will fail with an error. + +::: + +:::note Storage Deposit + +A call to withdraw means that a L1 output will be created. Because of this, the withdrawn +amount must be able to cover the L1 storage deposit. Otherwise, it will fail. + +::: + +### `transferAllowanceTo(a AgentID)` + +Transfers the specified allowance from the sender's L2 account to the given L2 account on +the chain. + +:::note + +When a transfer is made into an EVM account, an EVM tx will be created on the EVM side from the zero address (0x0000...) to the target account. +Information about what is being transferred will be encoded in the transaction's data using the following format: + +``` + + +``` + +The encoding used for this data can be found on [TIP-51](https://github.com/jorgemmsilva/tips/blob/b46d7bc36a0f7d4c2a1ad32ba25ec2abb4835cb3/tips/TIP-0051/tip-0051.md) + +::: + +#### Parameters + +- `a` (`AgentID`): The target L2 account. + +### `transferAccountToChain(g GasReserve)` + +Transfers the specified allowance from the sender SC's L2 account on +the target chain to the sender SC's L2 account on the origin chain. + +#### Parameters + +- `g` (`uint64`): Optional gas amount to reserve in the allowance for + the internal call to transferAllowanceTo(). Default 100 (MinGasFee). + +:::note Important Detailed Information + +[Read carefully before using this function.](xfer.md) + +::: + +### `nativeTokenCreate(t TokenScheme, tn TokenName, ts TokenSymbol, td TokenDecimal) s SerialNumber` + +Creates a new foundry and registers it as a ERC20 and IRC30 token. + +You can call this end point from the CLI using `wasp-cli chain create-native-token -h` + +#### Parameters + +- `t` ([`iotago::TokenScheme`](https://github.com/iotaledger/iota.go/blob/develop/token_scheme.go)): The token scheme + for the new foundry. +- `tn` (`string`): The token name +- `ts` (`string`): The token symbol +- `td` (`uint8`): The token decimals + +The storage deposit for the new foundry must be provided via allowance (only the minimum required will be used). + +#### Returns + +- `s` (`uint32`): The serial number of the newly created foundry + +### `nativeTokenModifySupply(s SerialNumber, d SupplyDeltaAbs, y DestroyTokens)` + +Mints or destroys tokens for the given foundry, which must be controlled by the caller. + +#### Parameters + +- `s` (`uint32`): The serial number of the foundry. +- `d` (positive `big.Int`): Amount to mint or destroy. +- `y` (optional `bool` - default: `false`): Whether to destroy tokens (`true`) or not (`false`). + +When minting new tokens, the storage deposit for the new output must be provided via an allowance. + +When destroying tokens, the tokens to be destroyed must be provided via an allowance. + +### `nativeTokenDestroy(s SerialNumber)` + +Destroys a given foundry output on L1, reimbursing the storage deposit to the caller. The foundry must be owned by the +caller. + +:::warning + +This operation cannot be reverted. + +::: + +#### Parameters + +- `s` (`uint32`): The serial number of the foundry. + + +### `foundryCreateNew(t TokenScheme) s SerialNumber` + +:::warning Deprecated + +This function is deprecated, please use [`nativeTokenCreate`](#nativetokencreatet-tokenscheme-s-serialnumber) instead + +::: + +Creates a new foundry with the specified token scheme, and assigns the foundry to the sender. + +You can call this end point from the CLI using `wasp-cli chain create-foundry -h` + +#### Parameters + +- `t` ([`iotago::TokenScheme`](https://github.com/iotaledger/iota.go/blob/develop/token_scheme.go)): The token scheme + for the new foundry. + +The storage deposit for the new foundry must be provided via allowance (only the minimum required will be used). + +#### Returns + +- `s` (`uint32`): The serial number of the newly created foundry + + +### `mintNFT(I ImmutableData, a AgentID, C CollectionID, w WithdrawOnMint)` + +Mints an NFT with ImmutableData `I` that will be owned by the AgentID `a`. +It's possible to mint as part of a collection `C` (the caller must be the owner of the collection NFT to mint new NFTs as part of said collection). +The mint can be done directly to any L1 address (it is not necessary for the target to have an account on the chain) + +#### Parameters + +- `I` (`[]byte`): ImmutableData for the NFT. +- `a` (`AgentID`): AgentID that will be the owner of the NFT. +- `C` (optional `NFTID` - default empty): collectionID (NFTID) for the NFT. +- `w` (optional `bool` - default `false`): whether to withdrawal the NFT in the minting step (can only be `true` when the targetAgentID is a L1 address). + +#### Returns + +- `D` (`MintID`): the internal ID of the NFT at the time of minting that can be used by users/contracts to obtain the resulting NFTID on the next block + +--- + +## Views + +### `balance(a AgentID)` + +Returns the fungible tokens owned by the given Agent ID on the chain. + +#### Parameters + +- `a` (`AgentID`): The account Agent ID. + +#### Returns + +A map of [`TokenID`](#tokenid) => `big.Int`. An empty token ID (a string of zero length) represents the L1 base token. + +### `balanceBaseToken(a AgentID)` + +Returns the amount of base tokens owned by any AgentID `a` on the chain. + +#### Parameters + +- `a` (`AgentID`): The account Agent ID. + +#### Returns + +- `B` (`uint64`): The amount of base tokens in the account. + +### `balanceNativeToken(a AgentID, N TokenID)` + +Returns the amount of native tokens with Token ID `N` owned by any AgentID `a` on the chain. + +#### Parameters + +- `a` (`AgentID`): The account Agent ID. +- `N` ([`TokenID`](#tokenid)): The Token ID. + +#### Returns + +- `B` (`big.Int`): The amount of native tokens in the account. + +### `totalAssets()` + +Returns the sum of all fungible tokens controlled by the chain. + +#### Returns + +A map of [`TokenID`](#tokenid) => `big.Int`. An empty token ID (a string of zero length) represents the L1 base token. + +### `accounts()` + +Returns a list of all agent IDs that own assets on the chain. + +#### Returns + +A map of `AgentiD` => `0x01`. + +### `getNativeTokenIDRegistry()` + +Returns a list of all native tokenIDs that are owned by the chain. + +#### Returns + +A map of [`TokenID`](#tokenid) => `0x01` + +### `nativeToken(s FoundrySerialNumber)` + +#### Parameters + +- `s` ([`FoundrySerialNumber`](#foundryserialnumber)): The Foundry serial number. + +#### Returns + +- `b`: [`iotago::FoundryOutput`](https://github.com/iotaledger/iota.go/blob/develop/output_foundry.go) + +### `accountNFTs(a AgentID)` + +Returns the NFT IDs for all NFTs owned by the given account. + +#### Parameters + +- `a` (`AgentID`): The account Agent ID + +#### Returns + +- `i` ([`Array`](https://github.com/iotaledger/wasp/blob/develop/packages/kv/collections/array.go) + of [`iotago::NFTID`](https://github.com/iotaledger/iota.go/blob/develop/output_nft.go)): + The NFT IDs owned by the account + +### `accountNFTAmount(a AgentID)` + +Returns the number of NFTs owned by the given account. + +#### Parameters + +- `a` (`AgentID`): The account Agent ID + +#### Returns + +- `A` (`uint32`) Amount of NFTs owned by the account + +### `accountNFTsInCollection(a AgentID)` + +Returns the NFT IDs for all NFTs in the given collection that are owned by the given account. + +#### Parameters + +- `a` (`AgentID`): The account Agent ID +- `C` (`NFTID`): The NFT ID of the collection + +#### Returns + +- `i` ([`Array`](https://github.com/iotaledger/wasp/blob/develop/packages/kv/collections/array.go) + of [`iotago::NFTID`](https://github.com/iotaledger/iota.go/blob/develop/output_nft.go)): + The NFT IDs in the collection owned by the account + +### `accountNFTAmountInCollection(a AgentID)` + +Returns the number of NFTs in the given collection that are owned by the given account. + +#### Parameters + +- `a` (`AgentID`): The account Agent ID +- `C` (`NFTID`): The NFT ID of the collection + +#### Returns + +- `A` (`uint32`) Amount of NFTs in the collection owned by the account + +### `accountFoundries(a AgentID)` + +Returns all foundries owned by the given account. + +#### Parameters + +- `a` (`AgentID`): The account Agent ID + +#### Returns + +A map of [`FoundrySerialNumber`](#foundryserialnumber) => `0x01` + +### `nftData(z NFTID)` + +Returns the data for a given NFT with ID `z` that is on the chain. + +#### Returns + +- `e`: [`NFTData`](#nftdata) + +### `NFTIDbyMintID(D MintID)` + +Returns the NFTID `z` for a given MintID `D`. + +#### Parameters + +- `D` (`MintID`): MintID producted at the time the NFT was minted + +#### Returns + +- `z` (`NFTID`): The ID of the NFT + +### `getAccountNonce(a AgentID)` + +Returns the current account nonce for a give AgentID `a`. +The account nonce is used to issue off-ledger requests. + +#### Parameters + +- `a` (`AgentID`): The account Agent ID. + +#### Returns + +- `n` (`uint64`): The account nonce. + +## Schemas + +### `FoundrySerialNumber` + +``` +FoundrySerialNumber = uint32 +``` + +### `TokenID` + +``` +TokenID = [38]byte +``` + +### `NFTID` + +``` +NFTID = [32]byte +``` + +### `MintID` + +``` +MintID = [6]byte +``` + +### `NFTData` + +`NFTData` is encoded as the concatenation of: + +- The issuer ([`iotago::Address`](https://github.com/iotaledger/iota.go/blob/develop/address.go)). +- The NFT metadata: the length (`uint16`) followed by the data bytes. +- The NFT owner (`AgentID`). diff --git a/docs/content/references/layer-2-smart-contracts/core-contracts/blob.md b/docs/content/references/layer-2-smart-contracts/core-contracts/blob.md new file mode 100644 index 00000000000..67e516e2a0a --- /dev/null +++ b/docs/content/references/layer-2-smart-contracts/core-contracts/blob.md @@ -0,0 +1,108 @@ +--- +description: The `blobs` contract maintains a registry of _blobs_ (a collection of arbitrary binary data) referenced from smart contracts via their hashes. +image: /img/logo/WASP_logo_dark.png +tags: + - core contracts + - bloc + - binary data + - store + - get + - entry points + - views + - reference +--- + +# The `blob` Contract + +The `blob` contract is one of the [core contracts](overview.md) on each IOTA Smart Contracts chain. + +The objective of the `blob` contract is to maintain an on-chain registry of _blobs_. +A blob is a collection of named chunks of binary data. + +``` +: +: +... +: +``` + +Both names and chunks are arbitrarily long byte slices. + +Blobs can be used to store arbitrary data like, for example, a collection of Wasm binaries needed to deploy a smart contract. + +Each blob in the registry is referenced by its hash. The hash is deterministically calculated from the concatenation of all pieces: + +``` +blobHash = hash( fieldName1 || binaryChunk1 || fieldName2 || binaryChunk2 || ... || fieldNameN || binaryChunkN) +``` + +Usually, field names are short strings, but their interpretation is use-case specific. + +Two predefined field names are interpreted by the VM while deploying smart contracts from binary: + +- _fieldname_ = `"v"` is interpreted as the _VM type_. +- _fieldname_ = `"p"` is interpreted as the _smart contract program binary_. + +If the field `"v"` is equal to the string `"wasmtime"`, the binary chunk of `"p"` is interpreted as WebAssembly binary, executable by the Wasmtime interpreter. + +The blob describing a smart contract may contain extra fields (ignored by the VM), for example: + +``` +"v" : VM type +"p" : smart contract program binary +"d" : data schema for data exchange between smart contract and outside sources and consumers +"s" : program sources in .zip format +``` + +--- + +## Entry Points + +### `storeBlob()` + +Stores a new blob in the registry. + +#### Parameters + +The key/value pairs of the received parameters are interpreted as the field/chunk pairs of the blob. + +#### Returns + +- `hash` (`[32]byte`): The hash of the stored blob. + +--- + +## Views + +### `getBlobInfo(hash BlobHash)` + +Returns the size of each chunk of the blob. + +#### Parameters + +- `hash` (`[32]byte`): The hash of the blob. + +#### Returns + +``` +: (uint32) +... +: (uint32) +``` + +### `getBlobField(hash BlobHash, field BlobField)` + +Returns the chunk associated with the given blob field name. + +#### Parameters + +- `hash` (`[32]byte`): The hash of the blob. +- `field` (`[]byte`): The field name. + +#### Returns + +- `bytes` (`[]byte`): The chunk associated with the given field name. + +### `listBlobs()` + +Returns a list of pairs `blob hash`: `total size of chunks` (`uint32`) for all blobs in the registry. diff --git a/docs/content/references/layer-2-smart-contracts/core-contracts/blocklog.md b/docs/content/references/layer-2-smart-contracts/core-contracts/blocklog.md new file mode 100644 index 00000000000..c78d57d17a6 --- /dev/null +++ b/docs/content/references/layer-2-smart-contracts/core-contracts/blocklog.md @@ -0,0 +1,202 @@ +--- +description: The `blocklog` contract keeps track of the blocks of requests processed by the chain. +image: /img/logo/WASP_logo_dark.png +tags: + - core contracts + - blocklog + - views + - information + - request status + - receipts + - events + - reference +--- + +# The `blocklog` Contract + +The `blocklog` contract is one of the [core contracts](overview.md) on each IOTA Smart Contracts chain. + +The `blocklog` contract keeps track of the blocks of requests processed by the chain, providing views to get request +status, receipts, block, and event details. + +To avoid having a monotonically increasing state size, only the latest `N` +blocks (and their events and receipts) are stored. This parameter can be configured +when [deploying the chain](/wasp/how-tos/setting-up-a-chain). + +--- + +## Entry Points + +### `retryUnprocessable(u requestID)` + +Tries to retry a given request that was marked as "unprocessable". + +:::note +"Unprocessable" requests are on-ledger requests that do not include enough base tokens to cover the deposit fees (example if an user tries to deposit many native tokens in a single output but only includes the minimum possible amount of base tokens). Such requests will be collected into an "unprocessable list" and users are able to deposit more funds onto their on-chain account and retry them afterwards. +::: + +#### Parameters + +- `u` ([`isc::RequestID`](https://github.com/iotaledger/wasp/blob/develop/packages/isc/request.go)): The requestID to be retried. (sender of the retry request must match the sender of the "unprocessable" request) + +--- + +## Views + +### `getBlockInfo(n uint32)` + +Returns information about the block with index `n`. + +#### Parameters + +- `n`: (optional `uint32`) The block index. Default: the latest block. + +#### Returns + +- `n` (`uint32`):The block index. +- `i` ([`BlockInfo`](#blockinfo)):The information about the block. + +### `getRequestIDsForBlock(n uint32)` + +Returns a list with all request IDs in the block with block index `n`. + +#### Parameters + +- `n` (optional `uint32`):The block index. The default value is the latest block. + +#### Returns + +- `n` (`uint32`):The block index. +- `u`: ([`Array`](https://github.com/iotaledger/wasp/blob/develop/packages/kv/collections/array.go) + of [`RequestID`](#requestid)) + +### `getRequestReceipt(u RequestID)` + +Returns the receipt for the request with the given ID. + +#### Parameters + +- `u` ([`RequestID`](#requestid)):The request ID. + +#### Returns + +- `n` (`uint32`):The block index. +- `r` (`uint16`):The request index within the block. +- `d` ([`RequestReceipt`](#requestreceipt)):The request receipt. + +### `getRequestReceiptsForBlock(n uint32)` + +Returns all the receipts in the block with index `n`. + +#### Parameters + +- `n` (optional `uint32`):The block index. Defaults to the latest block. + +#### Returns + +- `n` (`uint32`):The block index. +- `d`: ([`Array`](https://github.com/iotaledger/wasp/blob/develop/packages/kv/collections/array.go) + of [`RequestReceipt`](#requestreceipt)) + +### `isRequestProcessed(u RequestID)` + +Returns whether the request with ID `u` has been processed. + +#### Parameters + +- `u` ([`RequestID`](#requestid)):The request ID. + +#### Returns + +- `p` (`bool`):Whether the request was processed or not. + +### `getEventsForRequest(u RequestID)` + +Returns the list of events triggered during the execution of the request with ID `u`. + +### Parameters + +- `u` ([`RequestID`](#requestid)):The request ID. + +#### Returns + +- `e`: ([`Array`](https://github.com/iotaledger/wasp/blob/develop/packages/kv/collections/array.go) of `[]byte`). + +### `getEventsForBlock(n blockIndex)` + +Returns the list of events triggered during the execution of all requests in the block with index `n`. + +#### Parameters + +- `n` (optional `uint32`):The block index. Defaults to the latest block. + +#### Returns + +- `e`: ([`Array`](https://github.com/iotaledger/wasp/blob/develop/packages/kv/collections/array.go) of `[]byte`). + +### `getEventsForContract(h Hname)` + +Returns a list of events triggered by the smart contract with hname `h`. + +#### Parameters + +- `h` (`hname`):The smart contract’s hname. +- `f` (optional `uint32` - default: `0`):"From" block index. +- `t` (optional `uint32` - default: `MaxUint32`):"To" block index. + +#### Returns + +- `e`: ([`Array`](https://github.com/iotaledger/wasp/blob/develop/packages/kv/collections/array.go) of `[]byte`) + +### `hasUnprocessable(u requestID)` + +Asserts whether or not a given requestID (`u`) is present in the "unprocessable list" + +#### Parameters + +- `u` ([`isc::RequestID`](https://github.com/iotaledger/wasp/blob/develop/packages/isc/request.go)): The requestID to be checked + +#### Returns + +- `x` ([`bool`]) Whether or not the request exists in the "unprocessable list" + +--- + +## Schemas + +### `RequestID` + +A `RequestID` is encoded as the concatenation of: + +- Transaction ID (`[32]byte`). +- Transaction output index (`uint16`). + +### `BlockInfo` + +`BlockInfo` is encoded as the concatenation of: + +- The block timestamp (`uint64` UNIX nanoseconds). +- Amount of requests in the block (`uint16`). +- Amount of successful requests (`uint16`). +- Amount of off-ledger requests (`uint16`). +- Anchor transaction ID ([`iotago::TransactionID`](https://github.com/iotaledger/iota.go/blob/develop/transaction.go)). +- Anchor transaction sub-essence hash (`[32]byte`). +- Previous L1 commitment (except for block index 0). + - Trie root (`[20]byte`). + - Block hash (`[20]byte`). +- Total base tokens in L2 accounts (`uint64`). +- Total storage deposit (`uint64`). +- Gas burned (`uint64`). +- Gas fee charged (`uint64`). + +### `RequestReceipt` + +`RequestReceipt` is encoded as the concatenation of: + +- Gas budget (`uint64`). +- Gas burned (`uint64`). +- Gas fee charged (`uint64`). +- The request ([`isc::Request`](https://github.com/iotaledger/wasp/blob/develop/packages/isc/request.go)). +- Whether the request produced an error (`bool`). +- If the request produced an error, the + [`UnresolvedVMError`](./errors.md#unresolvedvmerror). diff --git a/docs/content/references/layer-2-smart-contracts/core-contracts/errors.md b/docs/content/references/layer-2-smart-contracts/core-contracts/errors.md new file mode 100644 index 00000000000..e4e5dbb2244 --- /dev/null +++ b/docs/content/references/layer-2-smart-contracts/core-contracts/errors.md @@ -0,0 +1,77 @@ +--- +description: 'The errors contract keeps a map of error codes to error message templates. These error codes are used in +request receipts.' +image: /img/logo/WASP_logo_dark.png +tags: + +- smart contracts +- core +- root +- initialization +- entry points +- fees +- ownership +- views +- reference +--- + +# The `errors` Contract + +The `errors` contract is one of the [core contracts](overview.md) on each IOTA Smart Contracts +chain. + +The `errors` contract keeps a map of error codes to error message templates. +This allows contracts to store lengthy error strings only once and then reuse them by just providing the error code (and +optional extra values) when producing an error, thus saving storage and gas. + +--- + +## Entry Points + +### `registerError(m ErrorMessageFormat) c ErrorCode` + +Registers an error message template. + +#### Parameters + +- `m` (`string`): The error message template, which supports standard [go verbs](https://pkg.go.dev/fmt#hdr-Printing) + for variable printing. + +#### Returns + +- `c` (`ErrorCode`): The error code of the registered template + +--- + +## Views + +### `getErrorMessageFormat(c ErrorCode) m ErrorMessageFormat` + +Returns the message template stored for a given error code. + +#### Parameters + +- `c` (`ErrorCode`): The error code of the registered template. + +#### Returns + +- `m` (`string`): The error message template. + +--- + +## Schemas + +### `ErrorCode` + +`ErrorCode` is encoded as the concatenation of: + +- The contract hname(`hname`). +- The error ID, calculated as the hash of the error template(`uint16`). + +### `UnresolvedVMError` + +`UnresolvedVMError` is encoded as the concatenation of: + +- The error code ([`ErrorCode`](#errorcode)). +- CRC32 checksum of the formatted string (`uint32`). +- The JSON-encoded list of parameters for the template (`string` prefixed with `uint16` size). diff --git a/docs/content/references/layer-2-smart-contracts/core-contracts/evm.md b/docs/content/references/layer-2-smart-contracts/core-contracts/evm.md new file mode 100644 index 00000000000..99be19b75bc --- /dev/null +++ b/docs/content/references/layer-2-smart-contracts/core-contracts/evm.md @@ -0,0 +1,170 @@ +--- +description: 'The evm core contract provides the necessary infrastructure to accept Ethereum transactions and execute +EVM code.' +image: /img/logo/WASP_logo_dark.png +tags: + +- smart contracts +- core +- root +- initialization +- entry points +- fees +- ownership +- views +- reference +--- + +# The `evm` Contract + +The `evm` contract is one of the [core contracts](overview.md) on each IOTA Smart Contracts chain. + +The `evm` core contract provides the necessary infrastructure to accept Ethereum transactions and execute EVM code. +It also includes the implementation of the [ISC Magic contract](../../how-tos/core-contracts/introduction.md). + +:::note + +For more information about how ISC supports EVM contracts, refer to the [EVM](../../getting-started/languages-and-vms.md#evmsolidity-based-smart-contracts) section. + +::: + +--- + +## Entry Points + +Most entry points of the `evm` core contract are meant to be accessed through the JSON-RPC service provided +automatically by the Wasp node so that the end users can use standard EVM tools like [MetaMask](https://metamask.io/). +We only list the entry points not exposed through the JSON-RPC interface in this document. + +### `init()` + +Called automatically when the ISC is deployed. + +Some parameters of the `evm` contract can be specified by passing them to the +[`root` contract `init` entry point](root.md#init): + +- `evmg` (optional [`GenesisAlloc`](#genesisalloc)): The genesis allocation. The balance of all accounts must be 0. +- `evmbk` (optional `int32` - default: keep all): Amount of EVM blocks to keep in the state. +- `evmchid` (optional `uint16` - default: 1074): EVM chain iD + + :::caution + + Re-using an existing Chain ID is not recommended and can be a security risk. For serious usage, register a unique + Chain ID on [Chainlist](https://chainlist.org/) and use that instead of the default. **It is not possible to change + the EVM chain ID after deployment.** + + ::: + +- `evmw` (optional [`GasRatio`](#gasratio) - default: `1:1`): The ISC to EVM gas ratio. + +### `registerERC20NativeToken` + +Registers an ERC20 contract to act as a proxy for the native tokens, at address +`0x107402xxxxxxxx00000000000000000000000000`, where `xxxxxxxx` is the +little-endian encoding of the foundry serial number. + +Only the foundry owner can call this endpoint. + +#### Parameters + +- `fs` (`uint32`): The foundry serial number +- `n` (`string`): The token name +- `t` (`string`): The ticker symbol +- `d` (`uint8`): The token decimals + +You can call this endpoint with the `wasp-cli register-erc20-native-token` command. See +`wasp-cli chain register-erc20-native-token -h` for instructions on how to use the command. + +### `registerERC20NativeTokenOnRemoteChain` + +Registers an ERC20 contract to act as a proxy for the native tokens **on another +chain**. + +The foundry must be controlled by this chain. Only the foundry owner can call +this endpoint. + +This endpoint is intended to be used in case the foundry is controlled by chain +A, and the owner of the foundry wishes to register the ERC20 contract on chain +B. In that case, the owner must call this endpoint on chain A with `target = +chain B`. The request to chain B is then sent as an on-ledger request. +After a few minutes, call +[`getERC20ExternalNativeTokenAddress`](#geterc20externalnativetokenaddress) +on chain B to find out the address of the ERC20 contract. + +#### Parameters + +- `fs` (`uint32`): The foundry serial number +- `n` (`string`): The token name +- `t` (`string`): The ticker symbol +- `d` (`uint8`): The token decimals +- `A` (`uint8`): The target chain address, where the ERC20 contract will be + registered. + +You can call this endpoint with the `wasp-cli register-erc20-native-token-on-remote-chain` command. See +`wasp-cli chain register-erc20-native-token-on-remote-chain -h` for instructions on how to use the command. + +### `registerERC20ExternalNativeToken` + +Registers an ERC20 contract to act as a proxy for the native tokens. + +Only an alias address can call this endpoint. + +If the foundry is controlled by another ISC chain, the foundry owner can call +[`registerERC20NativeTokenOnRemoteChain`](#registererc20nativetokenonchain) +on that chain, which will automatically call this endpoint on the chain set as +target. + +#### Parameters + +- `fs` (`uint32`): The foundry serial number +- `n` (`string`): The token name +- `t` (`string`): The ticker symbol +- `d` (`uint8`): The token decimals +- `T` (`TokenScheme`): The native token scheme + +### `registerERC721NFTCollection` + +Registers an ERC721 contract to act as a proxy for an NFT collection, at address +`0x107404xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`, where `xxx...` is the first 17 +bytes of the collection ID. + +The call will fail if the address is taken by another collection with the same prefix. + +#### Parameters + +- `C` (`NTFID`): The collection ID + +--- + +## Views + +### `getERC20ExternalNativeTokenAddress` + +Returns the address of an ERC20 contract registered with +[`registerERC20NativeTokenOnRemoteChain`](#registererc20nativetokenonchain). + +Only the foundry owner can call this endpoint. + +#### Parameters + +- `N` (`NativeTokenID`): The native token ID + +--- + +## Schemas + +### `GenesisAlloc` + +`GenesisAlloc` is encoded as the concatenation of: + +- Amount of accounts `n` (`uint32`). +- `n` times: + - Ethereum address (`[]byte` prefixed with `uint32` size). + - Account code (`[]byte` prefixed with `uint32` size). + - Amount of storage key/value pairs `m`(`uint32`). + - `m` times: + - Key (`[]byte` prefixed with `uint32` size). + - Value(`[]byte` prefixed with `uint32` size). + - Account balance (must be 0)(`[]byte` prefixed with `uint32` size). + - Account nonce (`uint64`). + - Account private key (may be used for tests)(`uint64`). diff --git a/docs/content/references/layer-2-smart-contracts/core-contracts/governance.md b/docs/content/references/layer-2-smart-contracts/core-contracts/governance.md new file mode 100644 index 00000000000..ab8e092379b --- /dev/null +++ b/docs/content/references/layer-2-smart-contracts/core-contracts/governance.md @@ -0,0 +1,355 @@ +--- +description: 'The `governance` contract defines the set of identities that constitute the state controller, access nodes, +who is the chain owner, and the fees for request execution.' +image: /img/logo/WASP_logo_dark.png +tags: + +- core contracts +- governance +- state controller +- identities +- chain owner +- rotate +- remove +- claim +- add +- chain info +- fee info +- reference +--- + +# The `governance` Contract + +The `governance` contract is one of the [core contracts](overview.md) on each IOTA Smart Contracts +chain. + +The `governance` contract provides the following functionalities: + +- It defines the identity set that constitutes the state controller (the entity that owns the state output via the chain + Alias Address). It is possible to add/remove addresses from the state controller (thus rotating the committee of + validators). +- It defines the chain owner (the L1 entity that owns the chain - initially whoever deployed it). The chain owner can + collect special fees and customize some chain-specific parameters. +- It defines the entities allowed to have an access node. +- It defines the fee policy for the chain (gas price, what token is used to pay for gas, and the validator fee share). + +--- + +## Fee Policy + +The Fee Policy looks like the following: + +```go +{ + GasPerToken Ratio32 // how many gas units are paid for each token + EVMGasRatio Ratio32 // the ratio at which EVM gas is converted to ISC gas + ValidatorFeeShare uint8 // percentage of the fees that are credited to the validators (0 - 100) +} +``` + +--- + +## Entry Points + +### `rotateStateController(S StateControllerAddress)` + +Called when the committee is about to be rotated to the new address `S`. + +If it succeeds, the next state transition will become a governance transition, thus updating the state controller in the +chain's Alias Output. If it fails, nothing happens. + +It can only be invoked by the chain owner. + +#### Parameters + +- `S` ([`iotago::Address`](https://github.com/iotaledger/iota.go/blob/develop/address.go)): The address of the next + state controller. Must be an + [allowed](#addallowedstatecontrolleraddresss-statecontrolleraddress) state controller address. + +### `addAllowedStateControllerAddress(S StateControllerAddress)` + +Adds the address `S` to the list of identities that constitute the state controller. + +It can only be invoked by the chain owner. + +#### Parameters + +- `S` ([`iotago::Address`](https://github.com/iotaledger/iota.go/blob/develop/address.go)): The address to add to the + set of allowed state controllers. + +### `removeAllowedStateControllerAddress(S StateControllerAddress)` + +Removes the address `S` from the list of identities that constitute the state controller. + +It can only be invoked by the chain owner. + +#### Parameters + +- `S` ([`iotago::Address`](https://github.com/iotaledger/iota.go/blob/develop/address.go)): The address to remove from + the set of allowed state controllers. + +### `delegateChainOwnership(o AgentID)` + +Sets the Agent ID `o` as the new owner for the chain. This change will only be effective +once [`claimChainOwnership`](#claimchainownership) is called by `o`. + +It can only be invoked by the chain owner. + +#### Parameters + +- `o` (`AgentID`): The Agent ID of the next chain owner. + +### `claimChainOwnership()` + +Claims the ownership of the chain if the caller matches the identity set +in [`delegateChainOwnership`](#delegatechainownershipo-agentid). + +### `setFeePolicy(g FeePolicy)` + +Sets the fee policy for the chain. + +#### Parameters + +- `g`: ([`FeePolicy`](#feepolicy)). + +It can only be invoked by the chain owner. + +### `setGasLimits(l GasLimits)` + +Sets the gas limits for the chain. + +#### Parameters + +- `l`: ([`GasLimits`](#gaslimits)). + +It can only be invoked by the chain owner. + +### `setEVMGasRatio(e Ratio32)` + +Sets the EVM gas ratio for the chain. + +#### Parameters + +- `e` ([`Ratio32`](#ratio32)): The EVM gas ratio. + +It can only be invoked by the chain owner. + +### `addCandidateNode(ip PubKey, ic Certificate, ia API, i ForCommittee)` + +Adds a node to the list of candidates. + +#### Parameters + +- `ip` (`[]byte`): The public key of the node to be added. +- `ic` (`[]byte`): The certificate is a signed binary containing both the node public key and their L1 address. +- `ia` (`string`): The API base URL for the node. +- `i` (optional `bool` - default: `false`): Whether the candidate node is being added to be part of the committee or + just an access node. + +It can only be invoked by the access node owner (verified via the Certificate field). + +### `revokeAccessNode(ip PubKey, ic Certificate, ia API, i ForCommittee)` + +Removes a node from the list of candidates. + +#### Parameters + +- `ip` (`[]byte`): The public key of the node to be removed. +- `ic` (`[]byte`): The certificate of the node to be removed. + +It can only be invoked by the access node owner (verified via the Certificate field). + +### `changeAccessNodes(n actions)` + +Iterates through the given map of actions and applies them. + +#### Parameters + +- `n` ([`Map`](https://github.com/iotaledger/wasp/blob/develop/packages/kv/collections/map.go) of `public key` => `byte`): + The list of actions to perform. Each byte value can be one of the following: + - `0`: Remove the access node from the access nodes list. + - `1`: Accept a candidate node and add it to the list of access nodes. + - `2`: Drop an access node from the access node and candidate lists. + +It can only be invoked by the chain owner. + +### `startMaintenance()` + +Starts the chain maintenance mode, meaning no further requests will be processed except +calls to the governance contract. + +It can only be invoked by the chain owner. + +### `stopMaintenance()` + +Stops the maintenance mode. + +It can only be invoked by the chain owner. + +### `setCustomMetadata(x bytes)` + +Changes optional extra metadata that is appended to the L1 AliasOutput. + +#### Parameters + +- `x` (`bytes`): the optional metadata + +### `setPayoutAgentID` + +`setPayoutAgentID` sets the payout AgentID. The default AgentID is the chain owner. Transaction fee will be taken to ensure the common account has minimum storage deposit which is in base token. The rest of transaction fee will be transferred to payout AgentID. + +#### Parameters + +- `s` (`AgentID`): the payout AgentID + +### `setMinCommonAccountBalance` + +`setMinCommonAccountBalance` sets the minimum balanced to be held in the common account. + +#### Parameters + +- `ms` (`AgentID`): the minimum common account balance + +--- + +## Views + +### `getAllowedStateControllerAddresses()` + +Returns the list of allowed state controllers. + +#### Returns + +- `a` ([`Array`](https://github.com/iotaledger/wasp/blob/develop/packages/kv/collections/array.go) + of [`iotago::Address`](https://github.com/iotaledger/iota.go/blob/develop/address.go)): The list of allowed state + controllers. + +### `getChainOwner()` + +Returns the AgentID of the chain owner. + +#### Returns + +- `o` (`AgentID`): The chain owner. + +### `getChainInfo()` + +Returns information about the chain. + +#### Returns + +- `c` (`ChainID`): The chain ID +- `o` (`AgentID`): The chain owner +- `g` ([`FeePolicy`](#feepolicy)): The gas fee policy +- `l` ([`GasLimits`](#gaslimits)): The gas limits +- `x` (`bytes`): The custom metadata + +### `getFeePolicy()` + +Returns the gas fee policy. + +#### Returns + +- `g` ([`FeePolicy`](#feepolicy)): The gas fee policy. + +### `getEVMGasRatio` + +Returns the ISC : EVM gas ratio. + +#### Returns + +- `e` ([`Ratio32`](#ratio32)): The ISC : EVM gas ratio. + +### `getGasLimits()` + +Returns the gas limits. + +#### Returns + +- `l` ([`GasLimits`](#gaslimits)): The gas limits. + +### `getChainNodes()` + +Returns the current access nodes and candidates. + +#### Returns + +- `ac` ([`Map`](https://github.com/iotaledger/wasp/blob/develop/packages/kv/collections/map.go) + of public key => `0x01`): The access nodes. +- `an` ([`Map`](https://github.com/iotaledger/wasp/blob/develop/packages/kv/collections/map.go) + of public key => [`AccessNodeInfo`](#accessnodeinfo)): The candidate nodes. + +### `getMaintenanceStatus()` + +Returns whether the chain is undergoing maintenance. + +#### Returns + +- `m` (`bool`): `true` if the chain is in maintenance mode + +### `getCustomMetadata()` + +Returns the extra metadata that is added to the chain AliasOutput. + +#### Returns + +- `x` (`bytes`): the optional metadata + +### `getPayoutAgentID` + +`getPayoutAgentID` gets the payout AgentID. + +Returns the payout AgentID of the chain. + +#### Returns + +- `s` (`AgentID`): the payout AgentID. + +### `getMinCommonAccountBalance` + +`getMinCommonAccountBalance` returns the minimum balanced to be held in the common account. + +#### Returns + +- `ms` (`uint64`): the minimum storage deposit. + +## Schemas + +### `Ratio32` + +A ratio between two values `x` and `y`, expressed as two `int32` numbers `a:b`, where `y = x * b/a`. + +`Ratio32` is encoded as the concatenation of the two `uint32` values `a` & `b`. + +### `FeePolicy` + +`FeePolicy` is encoded as the concatenation of: + +- The [`TokenID`](accounts.md#tokenid) of the token used to charge for gas. (`iotago.NativeTokenID`) + - If this value is `nil`, the gas fee token is the base token. +- Gas per token ([`Ratio32`](#ratio32)): expressed as an `a:b` (`gas/token`) ratio, meaning how many gas units each token pays for. +- Validator fee share. Must be between 0 and 100, meaning the percentage of the gas fees distributed to the + validators. (`uint8`) +- The ISC:EVM gas ratio ([`Ratio32`](#ratio32)): such that `ISC gas = EVM gas * a/b`. + +### `GasLimits` + +`GasLimits` is encoded as the concatenation of: + +- The maximum gas per block (`uint64`). A request that exceeds this limit is + skipped and processed in the next block. +- The minimum gas per request (`uint64`). If a request consumes less than this + value, it is charged for this instead. +- The maximum gas per request (`uint64`). If a request exceeds this limit, it + is rejected as failed. +- The maximum gas per external view call (`uint64). This is the gas budget + assigned to external view calls. + +### `AccessNodeInfo` + +`AccessNodeInfo` is encoded as the concatenation of: + +- The validator address. (`[]byte` prefixed by `uint16` size) +- The certificate. (`[]byte` prefixed by `uint16` size) +- Whether the access node is part of the committee of validators. (`bool`) +- The API base URL. (`string` prefixed by `uint16` size) diff --git a/docs/content/references/layer-2-smart-contracts/core-contracts/overview.md b/docs/content/references/layer-2-smart-contracts/core-contracts/overview.md new file mode 100644 index 00000000000..e3d70cd2419 --- /dev/null +++ b/docs/content/references/layer-2-smart-contracts/core-contracts/overview.md @@ -0,0 +1,37 @@ +--- +description: There currently are 6 core smart contracts that are always deployed on each chain, root, _default, accounts, blob, blocklog, and governance. +image: /img/banner/banner_wasp_core_contracts_overview.png +tags: + - smart contracts + - core + - initialization + - request handling + - on-chain ledger + - accounts + - data + - receipts + - reference +--- + +# Core Contracts + +![Wasp Node Core Contracts Overview](/img/banner/banner_wasp_core_contracts_overview.png) + +There are currently 7 core smart contracts that are always deployed on each +chain. These are responsible for the vital functions of the chain and +provide infrastructure for all other smart contracts: + +- [`root`](./root.md): Responsible for the initialization of the chain, maintains registry of deployed contracts. + +- [`accounts`](./accounts.md): Manages the on-chain ledger of accounts. + +- [`blob`](./blob.md): Responsible for the registry of binary objects of arbitrary size. + +- [`blocklog`](./blocklog.md): Keeps track of the blocks and receipts of requests that were processed by the chain. + +- [`governance`](./governance.md): Handles the administrative functions of the chain. For example: rotation of the committee of validators of the chain, fees and other chain-specific configurations. + +- [`errors`](./errors.md): Keeps a map of error codes to error messages templates. These error codes are used in request receipts. + +- [`evm`](./evm.md): Provides the necessary infrastructure to accept Ethereum + transactions and execute EVM code. diff --git a/docs/content/references/layer-2-smart-contracts/core-contracts/root.md b/docs/content/references/layer-2-smart-contracts/core-contracts/root.md new file mode 100644 index 00000000000..439e438befb --- /dev/null +++ b/docs/content/references/layer-2-smart-contracts/core-contracts/root.md @@ -0,0 +1,121 @@ +--- +description: 'The root contract is the first smart contract deployed on the chain. It functions as a smart contract +factory for the chain.' +image: /img/logo/WASP_logo_dark.png +tags: + +- smart contracts +- core +- root +- initialization +- entry points +- fees +- ownership +- views +- reference +--- + +# The `root` Contract + +The `root` contract is one of the [core contracts](overview.md) on each IOTA Smart Contracts +chain. + +The `root` contract is responsible for the initialization of the chain. +It is the first smart contract deployed on the chain and, upon receiving the `init` request, bootstraps the state of the +chain. +Deploying all of the other core contracts is a part of the state initialization. + +The `root` contract also functions as a smart contract factory for the chain: upon request, it deploys other smart +contracts and maintains an on-chain registry of smart contracts in its state. +The contract registry keeps a list of contract records containing their respective name, hname, description, and +creator. + +--- + +## Entry Points + +### `init()` + +The constructor. Automatically called immediately after confirmation of the origin transaction and never called again. +When executed, this function: + +- Initializes base values of the chain according to parameters. +- Sets the caller as the _chain owner_. +- Deploys all the core contracts. + +### `deployContract(ph ProgramHash, nm Name, ds Description)` + +Deploys a non-EVM smart contract on the chain if the caller has deployment permission. + +#### Parameters + +- `ph` (`[32]byte`): The hash of the binary _blob_ (that has been previously stored in the [`blob` contract](blob.md)). +- `nm` (`string`): The name of the contract to be deployed, used to calculate the + contract's _hname_. The hname must be unique among all contract hnames in the chain. +- `ds` (`string`): Description of the contract to be deployed. + +Any other parameters that are passed to the deployContract function will be passed on to +the `init` function of the smart contract being deployed. Note that this means that the +init parameter names cannot be the above ones, as they will have been filtered out. + +### `grantDeployPermission(dp AgentID)` + +The chain owner grants deploy permission to the agent ID `dp`. + +#### Parameters + +`dp`(AgentID): The agent ID. + +### `revokeDeployPermission(dp AgentID)` + +The chain owner revokes the deploy permission of the agent ID `dp`. + +#### Parameters + +`dp`(AgentID): The agent ID. + +### `requireDeployPermissions(de DeployPermissionsEnabled)` + +#### Parameters + +- `de` (`bool`): Whether permissions should be required to deploy a contract on the chain. + +By default, permissions are enabled (addresses need to be granted the right to deploy), but the chain owner can override +this setting to allow anyone to deploy contracts on the chain. + +--- + +## Views + +### `findContract(hn Hname)` + +Returns the record for a given smart contract with Hname `hn` (if it exists). + +#### Parameters + +`hn`: The smart contract’s Hname + +#### Returns + +- `cf` (`bool`): Whether or not the contract exists. +- `dt` ([`ContractRecord`](#contractrecord)): The requested contract record (if it exists). + +### `getContractRecords()` + +Returns the list of all smart contracts deployed on the chain and related records. + +#### Returns + +A map of `Hname` => [`ContractRecord`](#contractrecord) + +--- + +## Schemas + +### `ContractRecord` + +A `ContractRecord` is encoded as the concatenation of: + +- Program hash (`[32]byte`). +- Contract description (`string`). +- Contract name (`string`). diff --git a/docs/content/references/layer-2-smart-contracts/core-contracts/xfer.md b/docs/content/references/layer-2-smart-contracts/core-contracts/xfer.md new file mode 100644 index 00000000000..208316b58c8 --- /dev/null +++ b/docs/content/references/layer-2-smart-contracts/core-contracts/xfer.md @@ -0,0 +1,71 @@ +--- +description: 'The `transferAccountToChain` contract needs special consideration.' +image: /img/logo/WASP_logo_dark.png +tags: + - core contracts + - accounts + - deposit + - withdraw + - assets + - balance + - reference +--- + +# `accounts.transferAccountToChain` + +The `transferAccountToChain` function of the `accounts` contract is one that needs +careful consideration before use. Make sure you understand precisely how to use it to +prevent + +--- + +## Entry Point + +### `transferAccountToChain(g GasReserve)` + +Transfers the specified allowance from the sender SC's L2 account on +the target chain to the sender SC's L2 account on the origin chain. + +Caller must be a contract, and we will transfer the allowance from its L2 account +on the target chain to its L2 account on the origin chain. This requires that +this function takes the allowance into custody and in turn sends the assets as +allowance to the origin chain, where that chain's accounts.TransferAllowanceTo() +function then transfers it into the caller's L2 account on that chain. + +#### Parameters + +- `g` (`uint64`): Optional gas amount to reserve in the allowance for + the internal call to transferAllowanceTo(). Default 100 (MinGasFee). + But better to provide it so that it matches the fee structure. + +### IMPORTANT CONSIDERATIONS + +1. The caller contract needs to provide sufficient base tokens in its + allowance, to cover the gas fee GAS1 for this request. + Note that this amount depends on the fee structure of the target chain, + which can be different from the fee structure of the caller's own chain. + +2. The caller contract also needs to provide sufficient base tokens in + its allowance, to cover the gas fee GAS2 for the resulting request to + accounts.TransferAllowanceTo() on the origin chain. The caller needs to + also specify this GAS2 amount through the GasReserve parameter. + +3. The caller contract also needs to provide a storage deposit SD with + this request, holding enough base tokens _independent_ of the GAS1 and + GAS2 amounts. + Since this storage deposit is dictated by L1 we can use this amount as + storage deposit for the resulting accounts.TransferAllowanceTo() request, + where it will then be returned to the caller as part of the transfer. + +4. This means that the caller contract needs to provide at least + GAS1 + GAS2 + SD base tokens as assets to this request, and provide an + allowance to the request that is exactly GAS2 + SD + transfer amount. + Failure to meet these conditions may result in a failed request and + worst case the assets sent to accounts.TransferAllowanceTo() could be + irretrievably locked up in an account on the origin chain that belongs + to the accounts core contract of the target chain. + +5. The caller contract needs to set the gas budget for this request to + GAS1 to guard against unanticipated changes in the fee structure that + raise the gas price, otherwise the request could accidentally cannibalize + GAS2 or even SD, with potential failure and locked up assets as a result. diff --git a/docs/content/references/layer-2-smart-contracts/json-rpc-spec.md b/docs/content/references/layer-2-smart-contracts/json-rpc-spec.md new file mode 100644 index 00000000000..e15f1c9684d --- /dev/null +++ b/docs/content/references/layer-2-smart-contracts/json-rpc-spec.md @@ -0,0 +1,68 @@ +# JSON-RPC API + +The [JSON-RPC](https://www.jsonrpc.org/specification) is a stateless, lightweight remote procedure call (RPC) protocol. It defines several data structures and the rules around their processing. It is transport agnostic because the concepts can be used within the same process, over sockets, HTTP, or in various message-passing environments. It uses JSON (RFC 4627) as data format. + +This page deals with the JSON-RPC API used by EVM execution clients. + +## JSON-RPC Methods According to [Ethereum Client API](https://ethereum.org/en/developers/docs/apis/json-rpc/) + + +| Method | Description | Status | +|-----------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------| +| [eth_getBlockByHash](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblockbyhash) | _Returns information about a block by hash_ | ✅ | +| [eth_getBlockByNumber](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblockbynumber) | _Returns information about a block by number_ | ✅ | +| [eth_getBlockTransactionCountByHash](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblocktransactioncountbyhash) | _Returns the number of transactions in a block from a block matching the given block hash_ | ✅ | +| [eth_getBlockTransactionCountByNumber](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblocktransactioncountbynumber) | _Returns the number of transactions in a block matching the given block number_ | ✅ | +| [eth_getUncleCountByBlockHash](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getunclecountbyblockhash) | _Returns the number of uncles in a block from a block matching the given block hash_ | ✅ | +| [eth_getUncleCountByBlockNumber](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getunclecountbyblocknumber) | _Returns the number of uncles in a block from a block matching the given block number_ | ✅ | +| [eth_protocolVersion](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_protocolversion) | _Returns the current Ethereum protocol version_ | ✅ | +| [eth_chainId](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_chainid) | _Returns the chain ID of the current network_ | ✅ | +| [eth_syncing](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_syncing) | _Returns an object with data about the sync status or false-copy_ | ✅ | +| [eth_coinbase](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_coinbase) | _Returns the client Coinbase address_ | ✅ | +| [eth_accounts](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_accounts) | _Returns a list of addresses owned by client_ | ✅ | +| [eth_blockNumber](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_blocknumber) | _Returns the number of most recent block._ | ✅ | +| [eth_call](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_call) | _Executes a new message call immediately without creating a transaction on the blockchain_ | ✅ | +| [eth_estimateGas](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_estimategas) | _Generates and returns an estimate of how much gas is necessary to allow the transaction to complete._ | ✅ | +| [eth_gasPrice](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gasprice) | _Returns the current price per gas in wei_ | ✅ | +| [eth_feeHistory](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_feehistory) | _Returns fee history_ | ✅ | +| [eth_newFilter](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_newfilter) | _Creates a filter object, based on filter options, to notify when the state changes (logs)_ | ❌ | +| [eth_newBlockFilter](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_newblockfilter) | _Creates a filter in the node, to notify when a new block arrives_ | ❌ | +| [eth_newPendingTransactionFilter](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_newpendingtransactionfilter) | _Creates a filter in the node, to notify when new pending transactions arrive_ | ❌ | +| [eth_uninstallFilter](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_uninstallfilter) | _Uninstalls a filter with given id_ | ❌ | +| [eth_getFilterChanges](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getfilterchanges) | _Polling method for a filter, which returns an array of logs which occurred since last poll_| ❌ | +| [eth_getFilterLogs](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getfilterlogs) | _Returns an array of all logs matching filter with given id. Can compute the same results with an `eth_getLogs call`_ | ❌ | +| [eth_getLogs](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getlogs) | _Anytime a transaction is mined, we can see event logs for that transaction by making a request to eth_getLogs and then take actions based off those results_ | ✅ | +| [eth_mining](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_mining) | _Returns whether the client is actively mining new blocks_ | ✅ | +| [eth_hashrate](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_hashrate) | _Returns the number of hashes per second that the node is mining with_ | ✅ | +| [eth_sign](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sign) | _Returns an EIP-191 signature over the provided data._ | ✅ | +| [eth_signTransaction](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_signtransaction) | _Signs and submits a transaction_ | ✅ | +| [eth_getBalance](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getbalance) | _Returns the balance of the account of given address_ | ✅ | +| [eth_getStorageAt](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getstorageat) | _Returns the value from a storage position at a given address_ | ✅ | +| [eth_getTransactionCount](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactioncount) | _Returns the number of transactions sent from an address_ | ✅ | +| [eth_getCode](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getcode) | _Returns code at a given address_ | ✅ | +| [eth_sendTransaction](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sendtransaction) | _Signs and submits a transaction_ | ✅ | +| [eth_sendRawTransaction](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sendrawtransaction) | _Submits a raw transaction_ | ✅ | +| [eth_getTransactionByHash](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionbyhash) | _Returns the information about a transaction requested by transaction hash_ | ✅ | +| [eth_getTransactionByBlockHashAndIndex](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionbyblockhashandindex) | _Returns information about a transaction by block hash and transaction index position_ | ✅ | +| [eth_getTransactionByBlockNumberAndIndex](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionbyblocknumberandindex) | _Returns information about a transaction by block number and transaction index position_ | ✅ | +| [eth_getTransactionReceipt](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionrecepit) | _Returns the receipt of a transaction by transaction hash_ | ✅ | + + +## JSON-RPC methods according to the [Web3 Module API](https://openethereum.github.io/JSONRPC-web3-module) + +| Method | Description | Status | +|----------------------------------------------------------------------------------------------|------------------------------------------------------------------------|--------------------------------| +| [web3_clientVersion](https://openethereum.github.io/JSONRPC-web3-module#web3_clientversion) | _Returns the current client version_ | ✅ | +| [web3_sha](https://openethereum.github.io/JSONRPC-web3-module#web3_sha3) | _Returns Keccak-256 (not the standardized SHA3-256) of the given data_ | ✅ | + + + +## JSON-RPC methods according to the [Net Module API](https://openethereum.github.io/JSONRPC-net-module) + +| Method | Description | Status | +|----------------------------------------------------------------------------------|------------------------------------------------------------------------|--------------------------------| +| [net_listening](https://openethereum.github.io/JSONRPC-net-module#net_listening) | _Returns true if client is actively listening for network connections_ | ✅ | +| [net_peerCount](https://openethereum.github.io/JSONRPC-net-module#net_peercount) | _Returns number of peers currently connected to the client_ | ✅ | +| [net_version](https://openethereum.github.io/JSONRPC-net-module#net_version) | _Returns the current network protocol version_ | ✅ | + +You can find the complete set of available specs in the [Ethereum API Documentation](https://ethereum.github.io/execution-apis/api-documentation/). diff --git a/docs/content/references/layer-2-smart-contracts/magic-contract/introduction.md b/docs/content/references/layer-2-smart-contracts/magic-contract/introduction.md new file mode 100644 index 00000000000..3ca44996914 --- /dev/null +++ b/docs/content/references/layer-2-smart-contracts/magic-contract/introduction.md @@ -0,0 +1,38 @@ +--- +sidebar_position: 1 +--- + +import DocCardList from '@theme/DocCardList'; + +# Introduction + +This section documents the magic contract and all it's interfaces: + + + + +## Call a Native Contract + +You can call native contracts using [`ISC.sandbox.call`](https://github.com/iotaledger/wasp/blob/develop/packages/vm/core/evm/iscmagic/ISCSandbox.sol#L56): + +```solidity +pragma solidity >=0.8.5; + +import "@iota/iscmagic/ISC.sol"; + +contract MyEVMContract { + event EntropyEvent(bytes32 entropy); + + function callInccounter() public { + ISCDict memory params = ISCDict(new ISCDictItem[](1)); + bytes memory int64Encoded42 = hex"2A00000000000000"; + params.items[0] = ISCDictItem("counter", int64Encoded42); + ISCAssets memory allowance; + ISC.sandbox.call(ISC.util.hn("inccounter"), ISC.util.hn("incCounter"), params, allowance); + } +} +``` + +`ISC.util.hn` is used to get the `hname` of the `inccounter` contract and the +`incCounter` entry point. You can also call view entry points using +[ISC.sandbox.callView](https://github.com/iotaledger/wasp/blob/develop/packages/vm/core/evm/iscmagic/ISCSandbox.sol#L59). diff --git a/docs/content/references/layer-2-smart-contracts/wasm-lib-data-types.mdx b/docs/content/references/layer-2-smart-contracts/wasm-lib-data-types.mdx new file mode 100644 index 00000000000..28789a1772d --- /dev/null +++ b/docs/content/references/layer-2-smart-contracts/wasm-lib-data-types.mdx @@ -0,0 +1,104 @@ +--- +tags: + - data types + - WasmLib + - array + - proxies + - map + - reference + +description: The WasmLib provides direct support for the basic value data types that are found in all programming languages, and WasmLib versions of ISC-specific value data types. +image: /img/logo/WASP_logo_dark.png +--- + +# WasmLib Data Types + +You will need to manipulate data with your smart contracts. We distinguish two groups of +predefined data types that can be used in schema definition files. The WasmLib +implementations for each supported programming language provide full support for these +predefined data types. Each predefined data type can be (de)serialized as byte string or +as human-readable text string. + +## Basic Value Data Types + +These are mostly simple built-in scalar data types as provided by most programming +languages. Each integer data type has a clearly defined storage size. The +[Schema Tool](../schema/how-tos/usage.mdx) will attempt to use the closest matching built-in data type when +generating code for a specific language. + +- `BigInt` - An arbitrary-length unsigned integer. +- `Bool` - An 8-bit boolean value (0 or 1). +- `Bytes` - An arbitrary-length byte array. +- `Int8` - 8-bit signed integer value. +- `Int16` - 16-bit signed integer value. +- `Int32` - 32-bit signed integer value. +- `Int64` - 64-bit signed integer value. +- `String` - An arbitrary-length UTF-8 encoded string value. +- `Uint8` - 8-bit unsigned integer value. +- `Uint16` - 16-bit unsigned integer value. +- `Uint32` - 32-bit unsigned integer value. +- `Uint64` - 64-bit unsigned integer value. + +## ISC-specific Value Data Types + +These are ISC-specific value data types that are needed in the ISC sandbox function calls. +WasmLib provides its own implementations for each of the ISC value data types. + +- `Address` - A 33-byte encoded _Tangle_ address. +- `AgentID` - An ISC Agent ID (Address + Hname). +- `ChainID` - A 32-byte ISC Chain ID. +- `Hash` - A 32-byte hash value. +- `Hname` - A 4-byte unsigned integer hash value derived from a name string. +- `NftID` - A 32-byte ISC NFT ID. +- `RequestID` - A 34-byte ISC transaction request ID. +- `TokenID` - A 38-byte ISC token ID. + +## Full Matrix of WasmLib Types + +WasmLib implements a full set of [value proxies](../schema/proxies.mdx#value-proxies) for each +predefined value type that provide access to data on the ISC host. But there is one aspect +of this data that we have not considered yet. Some data provided by the host is mutable, +whereas other data may be immutable. To facilitate this distinction, each value proxy type +comes in two flavors that reflect this, and make sure that the data can only be used as +intended. + +The rule is that from an immutable container you can only derive immutable container and +value proxies. The referenced data can never be changed through immutable proxies. +Separating these constraints for types into separate value proxy types allows the use of +compile-time type-checking to enforce these constraints. To guard against client code that +tries to bypass them, the ISC sandbox will also check these constraints at runtime on the +host. + +| ISC type | WasmLib type | Mutable proxy | Immutable proxy | +|-----------|-------------------|------------------------|--------------------------| +| BigInt | Sc**BigInt** | ScMutable**BigInt** | ScImmutable**BigInt** | +| Bool | _boolean_ | ScMutable**Bool** | ScImmutable**Bool** | +| Bytes | _byte array_ | ScMutable**Bytes** | ScImmutable**Bytes** | +| Int8 | _8-bit signed_ | ScMutable**Int8** | ScImmutable**Int8** | +| Int16 | _16-bit signed_ | ScMutable**Int16** | ScImmutable**Int16** | +| Int32 | _32-bit signed_ | ScMutable**Int32** | ScImmutable**Int32** | +| Int64 | _64-bit signed_ | ScMutable**Int64** | ScImmutable**Int64** | +| String | _UTF-8 string_ | ScMutable**String** | ScImmutable**String** | +| Uint8 | _8-bit unsigned_ | ScMutable**Uint8** | ScImmutable**Uint8** | +| Uint16 | _16-bit unsigned_ | ScMutable**Uint16** | ScImmutable**Uint16** | +| Uint32 | _32-bit unsigned_ | ScMutable**Uint32** | ScImmutable**Uint32** | +| Uint64 | _64-bit unsigned_ | ScMutable**Uint64** | ScImmutable**Uint64** | +| | | | | +| Address | Sc**Address** | ScMutable**Address** | ScImmutable**Address** | +| AgentId | Sc**AgentId** | ScMutable**AgentId** | ScImmutable**AgentId** | +| ChainId | Sc**ChainId** | ScMutable**ChainId** | ScImmutable**ChainId** | +| Hash | Sc**Hash** | ScMutable**Hash** | ScImmutable**Hash** | +| Hname | Sc**Hname** | ScMutable**Hname** | ScImmutable**Hname** | +| NftID | Sc**NftID** | ScMutable**NftID** | ScImmutable**NftID** | +| RequestId | Sc**RequestId** | ScMutable**RequestId** | ScImmutable**RequestId** | +| TokenID | Sc**TokenID** | ScMutable**TokenID** | ScImmutable**TokenID** | + +The consistent naming makes it easy to remember the type names. Bool, Bytes, String, and +the integer types are the odd ones out. They are implemented in WasmLib by the closest +equivalents in the chosen WasmLib implementation programming language. + +The [Schema Tool](../schema/how-tos/usage.mdx) will automatically generate the proper immutable proxies +from the schema definition. For example, View functions will only be able to access the +[State](../schema/how-tos/state.mdx) map through immutable proxies. The same goes for the +[Params](../schema/how-tos/params.mdx) map that was passed into a Func or View, and for the +[Results](../schema/how-tos/results.mdx) map that was returned from a call to a Func or View. diff --git a/docs/content/sidebars/developer.js b/docs/content/sidebars/developer.js index 3fdb4cd2252..36b5f485bf9 100644 --- a/docs/content/sidebars/developer.js +++ b/docs/content/sidebars/developer.js @@ -3,260 +3,264 @@ // SPDX-License-Identifier: Apache-2.0 const developer = [ - 'developer/developer', - { - type: 'category', - label: 'Getting Started', - collapsed: false, - link: { - type: 'doc', - id: 'developer/getting-started', - }, - items: [ - 'developer/getting-started/iota-environment', - 'developer/getting-started/iota-install', - 'developer/getting-started/connect', - 'developer/getting-started/local-network', - 'developer/getting-started/get-address', - 'developer/getting-started/get-coins', - 'developer/getting-started/graphql-rpc', - { - type: 'category', - label: 'Your First IOTA dApp', - collapsed: false, - link: { - type: 'doc', - id: 'developer/getting-started/first-app/first-app', - }, - items: [ - 'developer/getting-started/first-app/write-package', - 'developer/getting-started/first-app/build-test', - 'developer/getting-started/first-app/publish', - 'developer/getting-started/first-app/debug', - 'developer/getting-started/first-app/client-tssdk', - ], - }, - ], - }, - { - type: 'category', - label: 'From Solidity/EVM to Move', - collapsed: true, - link: { - type: 'doc', - id: 'developer/evm-to-move', - }, - items: [ - 'developer/evm-to-move/why-move', - 'developer/evm-to-move/tooling-apis', - 'developer/evm-to-move/creating-token', - 'developer/evm-to-move/creating-nft', - ], - }, - { - type: 'category', - label: 'IOTA 101', - link: { - type: 'doc', - id: 'developer/iota-101', - }, - items: [ - { - type: 'category', - label: 'Move Overview',link: { - type: 'doc', - id: 'developer/iota-101/iota-move-concepts/iota-move-concepts', - }, - items: [ - 'developer/iota-101/iota-move-concepts/strings', - 'developer/iota-101/iota-move-concepts/collections', - 'developer/iota-101/iota-move-concepts/init', - 'developer/iota-101/iota-move-concepts/entry-functions', - 'developer/iota-101/iota-move-concepts/one-time-witness', - { - type: 'category', - label: 'Package Upgrades', - link: { - type: 'doc', - id: 'developer/iota-101/iota-move-concepts/packages/packages', - }, - items: [ - 'developer/iota-101/iota-move-concepts/packages/upgrade', - 'developer/iota-101/iota-move-concepts/packages/custom-policies', - ], - }, - { - type: 'category', - label: 'Patterns', - link: { - type: 'doc', - id: 'developer/iota-101/iota-move-concepts/patterns', - }, - items: [ - 'developer/iota-101/iota-move-concepts/patterns/capabilities', - 'developer/iota-101/iota-move-concepts/patterns/witness', - 'developer/iota-101/iota-move-concepts/patterns/transferrable-witness', - 'developer/iota-101/iota-move-concepts/patterns/hot-potato', - 'developer/iota-101/iota-move-concepts/patterns/id-pointer', - ], - }, - 'developer/iota-101/iota-move-concepts/conventions', - ], - }, - 'developer/graphql-rpc', - { - type: 'category', - label: 'Object Model', - items:[ - 'developer/iota-101/objects/object-model', - 'developer/iota-101/objects/shared-owned', - { - type: 'category', - label: 'Object Ownership', - link: { - type: 'doc', - id: 'developer/iota-101/objects/object-ownership/object-ownership', - }, - items: [ - 'developer/iota-101/objects/object-ownership/address-owned', - 'developer/iota-101/objects/object-ownership/immutable', - 'developer/iota-101/objects/object-ownership/shared', - 'developer/iota-101/objects/object-ownership/wrapped', - ], - }, - { - type: 'category', - label: 'Dynamic Fields', - link: { - type: 'doc', - id: 'developer/iota-101/objects/dynamic-fields/dynamic-fields', - }, - items: ['developer/iota-101/objects/dynamic-fields/tables-bags'], - }, - { - type: 'category', - label: 'Transfers', - link: { - type: 'doc', - id: 'developer/iota-101/objects/transfers/transfers', - }, - items: ['developer/iota-101/objects/transfers/custom-rules', - 'developer/iota-101/objects/transfers/transfer-to-object'], - }, - 'developer/iota-101/objects/events', - 'developer/iota-101/objects/versioning', - ] - }, - { - type: 'category', - label: 'Transactions', - link: { - type: 'doc', - id: 'developer/iota-101/transactions/transactions', - }, - items:[ - 'developer/iota-101/transactions/sign-and-send-txn', - { - type:'category', - label: 'Sponsored Transactions', - link: { - type: 'doc', - id: 'developer/iota-101/transactions/sponsor-txn', - }, - items:['developer/iota-101/transactions/sponsored-transactions'] - }, - 'developer/iota-101/transactions/gas-smashing', - { - type: 'category', - label: 'Working with PTBs', - items: [ - 'developer/iota-101/transactions/ptb/prog-txn-blocks', - 'developer/iota-101/transactions/ptb/building-ptb', - 'developer/iota-101/transactions/ptb/coin-mgt', - 'developer/iota-101/transactions/ptb/simulating-refs', - ], - }, - ] - }, - { - type: 'category', - label: 'Create Coins and Tokens', - link: { - type: 'doc', - id: 'developer/iota-101/create-coin/create-coin', - }, - items: [ - 'developer/iota-101/create-coin/regulated', - 'developer/iota-101/create-coin/in-game-token', - 'developer/iota-101/create-coin/loyalty', - ], - }, - 'developer/iota-101/create-nft', - 'developer/iota-101/using-events', - 'developer/iota-101/access-time', - ], - }, - { - type: 'category', - label: 'Cryptography', - link: { - type: 'doc', - id:'developer/cryptography/explanations/cryptography', - }, - items: [ - { - type: 'category', - label: 'Explanations', - items: [ - 'developer/cryptography/explanations/cryptography', - { - type: 'category', - label: 'Transaction Authentication', - link: { - type: 'doc', - id: 'developer/cryptography/explanations/transaction-auth', - }, - items: [ - 'developer/cryptography/explanations/transaction-auth/keys-addresses', - 'developer/cryptography/explanations/transaction-auth/signatures', - 'developer/cryptography/explanations/transaction-auth/multisig', - 'developer/cryptography/explanations/transaction-auth/offline-signing', - 'developer/cryptography/explanations/transaction-auth/intent-signing', - ], - }, - { - type: 'category', - label: 'zkLogin', - link: { - type: 'doc', - id: 'developer/cryptography/explanations/zklogin', - }, - items: ['developer/cryptography/explanations/zklogin/zklogin-example'], - }, - 'developer/cryptography/explanations/system/checkpoint-verification', - ], - }, - { - type: 'category', - label: 'How To', - items: [ - 'developer/cryptography/how-to/cryptography', - 'developer/cryptography/how-to/signing', - 'developer/cryptography/how-to/groth16', - 'developer/cryptography/how-to/hashing', - 'developer/cryptography/how-to/ecvrf',] - } - ], - }, - { - type: 'category', - label: 'Advanced Topics', - link: { - type: 'doc', - id: 'developer/advanced', - }, - items: [ - /*{ + 'developer/developer', + { + type: 'category', + label: 'Getting Started', + collapsed: false, + link: { + type: 'doc', + id: 'developer/getting-started', + }, + items: [ + 'developer/getting-started/iota-environment', + 'developer/getting-started/iota-install', + 'developer/getting-started/connect', + 'developer/getting-started/local-network', + 'developer/getting-started/get-address', + 'developer/getting-started/get-coins', + 'developer/getting-started/graphql-rpc', + { + type: 'category', + label: 'Your First IOTA dApp', + collapsed: false, + link: { + type: 'doc', + id: 'developer/getting-started/first-app/first-app', + }, + items: [ + 'developer/getting-started/first-app/write-package', + 'developer/getting-started/first-app/build-test', + 'developer/getting-started/first-app/publish', + 'developer/getting-started/first-app/debug', + 'developer/getting-started/first-app/client-tssdk', + ], + }, + ], + }, + { + type: 'category', + label: 'From Solidity/EVM to Move', + collapsed: true, + link: { + type: 'doc', + id: 'developer/evm-to-move', + }, + items: [ + 'developer/evm-to-move/why-move', + 'developer/evm-to-move/tooling-apis', + 'developer/evm-to-move/creating-token', + 'developer/evm-to-move/creating-nft', + ], + }, + { + type: 'category', + label: 'IOTA 101', + link: { + type: 'doc', + id: 'developer/iota-101', + }, + items: [ + { + type: 'category', + label: 'Move Overview', + link: { + type: 'doc', + id: 'developer/iota-101/iota-move-concepts/iota-move-concepts', + }, + items: [ + 'developer/iota-101/iota-move-concepts/strings', + 'developer/iota-101/iota-move-concepts/collections', + 'developer/iota-101/iota-move-concepts/init', + 'developer/iota-101/iota-move-concepts/entry-functions', + 'developer/iota-101/iota-move-concepts/one-time-witness', + { + type: 'category', + label: 'Package Upgrades', + link: { + type: 'doc', + id: 'developer/iota-101/iota-move-concepts/packages/packages', + }, + items: [ + 'developer/iota-101/iota-move-concepts/packages/upgrade', + 'developer/iota-101/iota-move-concepts/packages/custom-policies', + ], + }, + { + type: 'category', + label: 'Patterns', + link: { + type: 'doc', + id: 'developer/iota-101/iota-move-concepts/patterns', + }, + items: [ + 'developer/iota-101/iota-move-concepts/patterns/capabilities', + 'developer/iota-101/iota-move-concepts/patterns/witness', + 'developer/iota-101/iota-move-concepts/patterns/transferrable-witness', + 'developer/iota-101/iota-move-concepts/patterns/hot-potato', + 'developer/iota-101/iota-move-concepts/patterns/id-pointer', + ], + }, + 'developer/iota-101/iota-move-concepts/conventions', + ], + }, + 'developer/graphql-rpc', + { + type: 'category', + label: 'Object Model', + items: [ + 'developer/iota-101/objects/object-model', + 'developer/iota-101/objects/shared-owned', + { + type: 'category', + label: 'Object Ownership', + link: { + type: 'doc', + id: 'developer/iota-101/objects/object-ownership/object-ownership', + }, + items: [ + 'developer/iota-101/objects/object-ownership/address-owned', + 'developer/iota-101/objects/object-ownership/immutable', + 'developer/iota-101/objects/object-ownership/shared', + 'developer/iota-101/objects/object-ownership/wrapped', + ], + }, + { + type: 'category', + label: 'Dynamic Fields', + link: { + type: 'doc', + id: 'developer/iota-101/objects/dynamic-fields/dynamic-fields', + }, + items: ['developer/iota-101/objects/dynamic-fields/tables-bags'], + }, + { + type: 'category', + label: 'Transfers', + link: { + type: 'doc', + id: 'developer/iota-101/objects/transfers/transfers', + }, + items: [ + 'developer/iota-101/objects/transfers/custom-rules', + 'developer/iota-101/objects/transfers/transfer-to-object', + ], + }, + 'developer/iota-101/objects/events', + 'developer/iota-101/objects/versioning', + ], + }, + { + type: 'category', + label: 'Transactions', + link: { + type: 'doc', + id: 'developer/iota-101/transactions/transactions', + }, + items: [ + 'developer/iota-101/transactions/sign-and-send-txn', + { + type: 'category', + label: 'Sponsored Transactions', + link: { + type: 'doc', + id: 'developer/iota-101/transactions/sponsor-txn', + }, + items: ['developer/iota-101/transactions/sponsored-transactions'], + }, + 'developer/iota-101/transactions/gas-smashing', + { + type: 'category', + label: 'Working with PTBs', + items: [ + 'developer/iota-101/transactions/ptb/prog-txn-blocks', + 'developer/iota-101/transactions/ptb/building-ptb', + 'developer/iota-101/transactions/ptb/coin-mgt', + 'developer/iota-101/transactions/ptb/simulating-refs', + ], + }, + ], + }, + { + type: 'category', + label: 'Create Coins and Tokens', + link: { + type: 'doc', + id: 'developer/iota-101/create-coin/create-coin', + }, + items: [ + 'developer/iota-101/create-coin/regulated', + 'developer/iota-101/create-coin/in-game-token', + 'developer/iota-101/create-coin/loyalty', + ], + }, + 'developer/iota-101/create-nft', + 'developer/iota-101/using-events', + 'developer/iota-101/access-time', + ], + }, + { + type: 'category', + label: 'Cryptography', + link: { + type: 'doc', + id: 'developer/cryptography/explanations/cryptography', + }, + items: [ + { + type: 'category', + label: 'Explanations', + items: [ + 'developer/cryptography/explanations/cryptography', + { + type: 'category', + label: 'Transaction Authentication', + link: { + type: 'doc', + id: 'developer/cryptography/explanations/transaction-auth', + }, + items: [ + 'developer/cryptography/explanations/transaction-auth/keys-addresses', + 'developer/cryptography/explanations/transaction-auth/signatures', + 'developer/cryptography/explanations/transaction-auth/multisig', + 'developer/cryptography/explanations/transaction-auth/offline-signing', + 'developer/cryptography/explanations/transaction-auth/intent-signing', + ], + }, + { + type: 'category', + label: 'zkLogin', + link: { + type: 'doc', + id: 'developer/cryptography/explanations/zklogin', + }, + items: ['developer/cryptography/explanations/zklogin/zklogin-example'], + }, + 'developer/cryptography/explanations/system/checkpoint-verification', + ], + }, + { + type: 'category', + label: 'How To', + items: [ + 'developer/cryptography/how-to/cryptography', + 'developer/cryptography/how-to/signing', + 'developer/cryptography/how-to/groth16', + 'developer/cryptography/how-to/hashing', + 'developer/cryptography/how-to/ecvrf', + ], + }, + ], + }, + { + type: 'category', + label: 'Advanced Topics', + link: { + type: 'doc', + id: 'developer/advanced', + }, + items: [ + /*{ type: 'category', label: 'Efficient Smart Contracts', link: { @@ -265,116 +269,536 @@ const developer = [ }, items: ['developer/advanced/min-gas-fees'], },*/ - 'developer/advanced/graphql-migration', - 'developer/advanced/move-2024-migration', - 'developer/advanced/asset-tokenization', - 'developer/advanced/custom-indexer', - 'developer/advanced/stardust-on-move', - ], - }, - { - type: 'category', - label: 'App Examples', - link: { - type: 'doc', - id: 'developer/app-examples', - }, - items: [ - 'developer/app-examples/blackjack', - 'developer/app-examples/coin-flip', - 'developer/app-examples/e2e-counter', - 'developer/app-examples/plinko', - 'developer/app-examples/recaptcha', - 'developer/app-examples/tic-tac-toe', - { - type: 'category', - label: 'Trustless Token Swap', - link: { - type: 'doc', - id: 'developer/app-examples/trustless-token-swap', - }, - items: [ - 'developer/app-examples/trustless-token-swap/backend', - 'developer/app-examples/trustless-token-swap/indexer-api', - 'developer/app-examples/trustless-token-swap/frontend', - ], - }, - ], - }, - { - type:'category', - label: 'Standards', - items: [ - 'developer/standards/standards', - 'developer/standards/coin', - 'developer/standards/coin-manager', - { - type: 'category', - label: 'Closed-Loop Token', - link: { - type: 'doc', - id: 'developer/standards/closed-loop-token', - }, - items: [ - 'developer/standards/closed-loop-token/action-request', - 'developer/standards/closed-loop-token/token-policy', - 'developer/standards/closed-loop-token/spending', - 'developer/standards/closed-loop-token/rules', - 'developer/standards/closed-loop-token/coin-token-comparison', - ], - }, - 'developer/standards/kiosk', - 'developer/standards/kiosk-apps', - { - type: 'category', - label: 'DeepBook', - link: { - type: 'doc', - id: 'developer/standards/deepbook', - }, - items: [ - 'developer/standards/deepbook/design', - 'developer/standards/deepbook/orders', - 'developer/standards/deepbook/pools', - 'developer/standards/deepbook/query-the-pool', - 'developer/standards/deepbook/routing-a-swap', - 'developer/standards/deepbook/trade-and-swap', - ], - }, - 'developer/standards/display', - 'developer/standards/wallet-standard', - ] - }, - 'developer/dev-cheat-sheet', - { - type:'category', - label: 'Integrate Your Exchange', - items:[ - 'developer/exchange-integration/exchange-integration', + 'developer/advanced/graphql-migration', + 'developer/advanced/move-2024-migration', + 'developer/advanced/asset-tokenization', + 'developer/advanced/custom-indexer', + 'developer/advanced/stardust-on-move', + ], + }, + { + type: 'category', + label: 'App Examples', + link: { + type: 'doc', + id: 'developer/app-examples', + }, + items: [ + 'developer/app-examples/blackjack', + 'developer/app-examples/coin-flip', + 'developer/app-examples/e2e-counter', + 'developer/app-examples/plinko', + 'developer/app-examples/recaptcha', + 'developer/app-examples/tic-tac-toe', + { + type: 'category', + label: 'Trustless Token Swap', + link: { + type: 'doc', + id: 'developer/app-examples/trustless-token-swap', + }, + items: [ + 'developer/app-examples/trustless-token-swap/backend', + 'developer/app-examples/trustless-token-swap/indexer-api', + 'developer/app-examples/trustless-token-swap/frontend', + ], + }, + ], + }, + { + type: 'category', + label: 'Standards', + items: [ + 'developer/standards/standards', + 'developer/standards/coin', + 'developer/standards/coin-manager', + { + type: 'category', + label: 'Closed-Loop Token', + link: { + type: 'doc', + id: 'developer/standards/closed-loop-token', + }, + items: [ + 'developer/standards/closed-loop-token/action-request', + 'developer/standards/closed-loop-token/token-policy', + 'developer/standards/closed-loop-token/spending', + 'developer/standards/closed-loop-token/rules', + 'developer/standards/closed-loop-token/coin-token-comparison', + ], + }, + 'developer/standards/kiosk', + 'developer/standards/kiosk-apps', + { + type: 'category', + label: 'DeepBook', + link: { + type: 'doc', + id: 'developer/standards/deepbook', + }, + items: [ + 'developer/standards/deepbook/design', + 'developer/standards/deepbook/orders', + 'developer/standards/deepbook/pools', + 'developer/standards/deepbook/query-the-pool', + 'developer/standards/deepbook/routing-a-swap', + 'developer/standards/deepbook/trade-and-swap', + ], + }, + 'developer/standards/display', + 'developer/standards/wallet-standard', + ], + }, + 'developer/dev-cheat-sheet', - { - type: 'category', - label: 'Migrating IOTA/Shimmer Stardust', - link: { - type: 'doc', - id: 'developer/stardust/stardust-migration', - }, - items: [ - 'developer/stardust/exchanges', - 'developer/stardust/move-models', - 'developer/stardust/addresses', - 'developer/stardust/units', - 'developer/stardust/migration-process', - 'developer/stardust/claiming', - 'developer/stardust/vested', - 'developer/stardust/testing', - 'developer/stardust/if-tools', - 'developer/stardust/faq', - 'developer/stardust/advanced', - ], - }, - ] - }, - ] -; + { + type: 'category', + label: 'Solidity/EVM Smart Contracts', + link: { + type: 'doc', + id: 'guides/developer/layer-2-smart-contracts/introduction', + }, + items: [ + { + type: 'doc', + label: 'Introduction', + id: 'guides/developer/layer-2-smart-contracts/introduction', + }, + { + type: 'category', + label: 'Getting Started', + items: [ + { + type: 'doc', + label: 'Languages & VMs', + id: 'guides/developer/layer-2-smart-contracts/getting-started/languages-and-vms', + }, + 'getting-started/quick-start', + 'getting-started/compatibility', + { + type: 'doc', + label: 'Networks & Chains', + id: 'guides/developer/layer-2-smart-contracts/getting-started/networks-and-chains', + }, + { + type: 'doc', + label: 'Tools', + id: 'guides/developer/layer-2-smart-contracts/getting-started/tools', + }, + ], + }, + { + type: 'category', + label: 'How To', + items: [ + 'how-tos/introduction', + { + type: 'doc', + label: 'Send Funds from L1 to L2', + id: 'guides/developer/layer-2-smart-contracts/how-tos/send-funds-from-L1-to-L2', + }, + { + type: 'doc', + label: 'Create a Basic Contract', + id: 'guides/developer/layer-2-smart-contracts/how-tos/create-a-basic-contract', + }, + { + type: 'doc', + label: 'Deploy a Smart Contract', + id: 'guides/developer/layer-2-smart-contracts/how-tos/deploy-a-smart-contract', + }, + { + type: 'doc', + label: 'Create Custom Tokens - ERC20', + id: 'guides/developer/layer-2-smart-contracts/how-tos/ERC20', + }, + { + type: 'doc', + label: 'Send ERC20 Tokens Across Chains', + id: 'guides/developer/layer-2-smart-contracts/how-tos/send-ERC20-across-chains', + }, + { + type: 'doc', + label: 'Create NFTs - ERC721', + id: 'guides/developer/layer-2-smart-contracts/how-tos/ERC721', + }, + { + type: 'doc', + label: 'Send NFTs Across Chains', + id: 'guides/developer/layer-2-smart-contracts/how-tos/send-NFTs-across-chains', + }, + { + type: 'doc', + label: 'Test Smart Contracts', + id: 'guides/developer/layer-2-smart-contracts/how-tos/test-smart-contracts', + }, + { + type: 'category', + label: 'Interact with the Core Contracts', + items: [ + { + type: 'doc', + label: 'Introduction', + id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/introduction', + }, + { + type: 'category', + label: 'Basics', + items: [ + { + type: 'doc', + label: 'Get Native Assets Balance', + id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/get-balance', + }, + { + type: 'category', + label: 'Allowance', + items: [ + { + type: 'doc', + label: 'Allow', + id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/allow', + }, + { + type: 'doc', + label: 'Get Allowance', + id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/get-allowance', + }, + { + type: 'doc', + label: 'Take Allowance', + id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/take-allowance', + }, + ], + }, + { + type: 'doc', + label: 'Send Assets to L1', + id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/send-assets-to-l1', + }, + ], + }, + { + type: 'category', + label: 'Token', + items: [ + { + label: 'Introduction', + type: 'doc', + id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/introduction', + }, + { + type: 'doc', + label: 'Create a Native Token', + id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/create-native-token', + }, + { + type: 'doc', + label: 'Mint Native Tokens', + id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/mint-token', + }, + { + type: 'doc', + label: 'Custom ERC20 Functions', + id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/erc20-native-token', + }, + { + type: 'doc', + label: 'Create a Foundry', + id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/create-foundry', + }, + { + type: 'doc', + label: 'Register Token as ERC20', + id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/register-token', + }, + ], + }, + { + type: 'category', + label: 'NFT', + items: [ + { + label: 'Introduction', + type: 'doc', + id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/introduction', + }, + { + type: 'doc', + label: 'Mint an NFT', + id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/mint-nft', + }, + { + type: 'doc', + label: 'Use as ERC721', + id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/use-as-erc721', + }, + ], + }, + { + type: 'doc', + label: 'Get Randomness on L2', + id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/get-randomness-on-l2', + }, + { + type: 'doc', + label: 'Call and Call View', + id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/call-view', + }, + ], + }, + ], + }, + { + type: 'category', + label: 'Explanations', + items: [ + { + type: 'doc', + label: 'Anatomy of a Smart Contract', + id: 'guides/developer/layer-2-smart-contracts/explanations/smart-contract-anatomy', + }, + { + type: 'doc', + label: 'Sandbox Interface', + id: 'guides/developer/layer-2-smart-contracts/explanations/sandbox', + }, + { + type: 'doc', + label: 'Calling a Smart Contract', + id: 'guides/developer/layer-2-smart-contracts/explanations/invocation', + }, + { + type: 'doc', + label: 'State, Transitions and State Anchoring', + id: 'guides/developer/layer-2-smart-contracts/explanations/states', + }, + { + type: 'doc', + label: 'State manager', + id: 'guides/developer/layer-2-smart-contracts/explanations/state_manager', + }, + { + type: 'doc', + label: 'Validators and Access Nodes', + id: 'guides/developer/layer-2-smart-contracts/explanations/validators', + }, + { + type: 'doc', + label: 'Consensus', + id: 'guides/developer/layer-2-smart-contracts/explanations/consensus', + }, + { + type: 'doc', + label: 'How Accounts Work', + id: 'guides/developer/layer-2-smart-contracts/explanations/how-accounts-work', + }, + { + type: 'link', + label: 'Core Contracts', + href: '/isc/reference/core-contracts/overview', + }, + ], + }, + { + type: 'category', + label: 'Test with Solo', + items: [ + { + label: 'Getting Started', + id: 'guides/developer/layer-2-smart-contracts/solo/getting-started', + type: 'doc', + }, + { + type: 'category', + label: 'How To', + items: [ + { + type: 'doc', + label: 'First Example', + id: 'guides/developer/layer-2-smart-contracts/solo/how-tos/first-example', + }, + { + type: 'doc', + label: 'The L1 Ledger', + id: 'guides/developer/layer-2-smart-contracts/solo/how-tos/the-l1-ledger', + }, + { + type: 'doc', + label: 'Deploy a Smart Contract', + id: 'guides/developer/layer-2-smart-contracts/solo/how-tos/deploying-sc', + }, + { + type: 'doc', + label: 'Invoke a Smart Contract', + id: 'guides/developer/layer-2-smart-contracts/solo/how-tos/invoking-sc', + }, + { + type: 'doc', + label: 'Call a View', + id: 'guides/developer/layer-2-smart-contracts/solo/how-tos/view-sc', + }, + { + type: 'doc', + label: 'Error Handling', + id: 'guides/developer/layer-2-smart-contracts/solo/how-tos/error-handling', + }, + { + type: 'doc', + label: 'Accounts', + id: 'guides/developer/layer-2-smart-contracts/solo/how-tos/the-l2-ledger', + }, + { + type: 'doc', + label: 'Test Smart Contracts', + id: 'guides/developer/layer-2-smart-contracts/solo/how-tos/test', + }, + { + type: 'doc', + label: 'Example Tests', + id: 'guides/developer/layer-2-smart-contracts/solo/how-tos/examples', + }, + { + type: 'doc', + label: 'Colored Tokens and Time Locks', + id: 'guides/developer/layer-2-smart-contracts/solo/how-tos/timelock', + }, + ], + }, + ], + }, + { + type: 'category', + label: 'Wasm - Schema Tool', + items: [ + { + type: 'doc', + label: 'The Schema Tool', + id: 'guides/developer/layer-2-smart-contracts/schema/introduction', + }, + { + type: 'doc', + label: 'Data Access Proxies', + id: 'guides/developer/layer-2-smart-contracts/schema/proxies', + }, + { + type: 'category', + label: 'How To', + items: [ + { + type: 'doc', + label: 'Create a Schema', + id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/usage', + }, + { + type: 'doc', + label: 'Define the State', + id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/state', + }, + { + type: 'doc', + label: 'Use Structured Data Types', + id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/structs', + }, + { + type: 'doc', + label: 'Generate Type Definitions', + id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/typedefs', + }, + { + type: 'doc', + label: 'Trigger Events', + id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/events', + }, + { + type: 'doc', + label: 'Define Functions', + id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/funcs', + }, + { + type: 'doc', + label: 'Limit Access', + id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/access', + }, + { + type: 'doc', + label: 'Define Function Parameters', + id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/params', + }, + { + type: 'doc', + label: 'Define Function Results', + id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/results', + }, + { + type: 'doc', + label: 'Use Thunk Functions', + id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/thunks', + }, + { + type: 'doc', + label: 'Use View-Only Functions', + id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/views', + }, + { + type: 'doc', + label: 'Initialize a Smart Contract', + id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/init', + }, + { + type: 'doc', + label: 'Transfer Tokens', + id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/transfers', + }, + { + type: 'doc', + label: 'Add Function Descriptors', + id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/funcdesc', + }, + { + type: 'doc', + label: 'Call Functions', + id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/call', + }, + { + type: 'doc', + label: 'Post Asynchronous Requests', + id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/post', + }, + ], + }, + ], + }, + ], + }, + { + type: 'category', + label: 'Integrate Your Exchange', + items: [ + 'developer/exchange-integration/exchange-integration', + + { + type: 'category', + label: 'Migrating IOTA/Shimmer Stardust', + link: { + type: 'doc', + id: 'developer/stardust/stardust-migration', + }, + items: [ + 'developer/stardust/exchanges', + 'developer/stardust/move-models', + 'developer/stardust/addresses', + 'developer/stardust/units', + 'developer/stardust/migration-process', + 'developer/stardust/claiming', + 'developer/stardust/vested', + 'developer/stardust/testing', + 'developer/stardust/if-tools', + 'developer/stardust/faq', + 'developer/stardust/advanced', + ], + }, + ], + }, +]; module.exports = developer; diff --git a/docs/content/sidebars/operator.js b/docs/content/sidebars/operator.js index b66d6fd3884..585df7c8539 100644 --- a/docs/content/sidebars/operator.js +++ b/docs/content/sidebars/operator.js @@ -13,6 +13,61 @@ const operator = [ 'operator/validator-committee', 'operator/validator-tasks', 'operator/node-tools', - + { + type: 'category', + label: 'IOTA EVM Network', + link: { + type: 'doc', + id: 'guides/operator/layer-2-smart-contracts-node/how-tos/running-a-node', + }, + items: [ + { + type: 'category', + label: 'How To', + collapsed: false, + items: [ + { + type: 'doc', + id: 'guides/operator/layer-2-smart-contracts-node/how-tos/running-a-node', + label: 'Run a Node', + }, + { + type: 'doc', + id: 'guides/operator/layer-2-smart-contracts-node/how-tos/running-an-access-node', + label: 'Run an Access Node', + }, + { + id: 'guides/operator/layer-2-smart-contracts-node/how-tos/wasp-cli', + label: 'Configure wasp-cli', + type: 'doc', + }, + { + id: 'guides/operator/layer-2-smart-contracts-node/how-tos/setting-up-a-chain', + label: 'Set Up a Chain', + type: 'doc', + }, + { + id: 'guides/operator/layer-2-smart-contracts-node/how-tos/chain-management', + label: 'Manage a Chain', + type: 'doc', + }, + ], + }, + { + type: 'category', + label: 'Reference', + items: [ + { + type: 'doc', + id: 'guides/operator/layer-2-smart-contracts-node/reference/configuration', + }, + { + type: 'doc', + id: 'guides/operator/layer-2-smart-contracts-node/reference/metrics', + }, + ], + }, + ], + }, ]; module.exports = operator; diff --git a/docs/content/sidebars/references.js b/docs/content/sidebars/references.js index baf2bf87ecb..d5b0a3bd9bf 100644 --- a/docs/content/sidebars/references.js +++ b/docs/content/sidebars/references.js @@ -227,6 +227,84 @@ const references = [ }, ], }, + { + type: 'category', + label: 'Layer 2 Smart Contracts', + items: [ + 'references/layer-2-smart-contracts/json-rpc-spec', + { + type: 'category', + label: 'Magic Contract', + items: [ + { + type: 'autogenerated', + dirName: 'references/layer-2-smart-contracts/magic-contract', + }, + ], + }, + { + type: 'category', + label: 'Core Contracts', + items: [ + { + type: 'doc', + label: 'Overview', + id: 'references/layer-2-smart-contracts/core-contracts/overview', + }, + { + type: 'doc', + label: 'root', + id: 'references/layer-2-smart-contracts/core-contracts/root', + }, + { + type: 'doc', + label: 'accounts', + id: 'references/layer-2-smart-contracts/core-contracts/accounts', + }, + { + type: 'doc', + label: 'blob', + id: 'references/layer-2-smart-contracts/core-contracts/blob', + }, + { + type: 'doc', + label: 'blocklog', + id: 'references/layer-2-smart-contracts/core-contracts/blocklog', + }, + { + type: 'doc', + label: 'governance', + id: 'references/layer-2-smart-contracts/core-contracts/governance', + }, + { + type: 'doc', + label: 'errors', + id: 'references/layer-2-smart-contracts/core-contracts/errors', + }, + { + type: 'doc', + label: 'EVM', + id: 'references/layer-2-smart-contracts/core-contracts/evm', + }, + ], + }, + { + type: 'category', + label: 'ISC Utilities', + items: [ + { + type: 'autogenerated', + dirName: 'references/layer-2-smart-contracts/iscutils', + }, + ], + }, + { + type: 'doc', + label: 'WasmLib Data Types', + id: 'references/layer-2-smart-contracts/wasm-lib-data-types', + }, + ], + }, 'references/iota-glossary', { type: 'category', From ba02fc86e7a0070952c6c173cdb475921b840a7e Mon Sep 17 00:00:00 2001 From: Jeroen van den Hout Date: Sun, 9 Jun 2024 23:54:30 +0200 Subject: [PATCH 09/37] feat(docs): add ISC reference script --- docs/site/.gitignore | 1 + docs/site/package.json | 4 ++-- docs/site/scripts/get_wasp_references.sh | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100755 docs/site/scripts/get_wasp_references.sh diff --git a/docs/site/.gitignore b/docs/site/.gitignore index de81e463ce5..460502c8f56 100644 --- a/docs/site/.gitignore +++ b/docs/site/.gitignore @@ -11,6 +11,7 @@ # Generated files .docusaurus .cache-loader +/tmp # Misc .DS_Store diff --git a/docs/site/package.json b/docs/site/package.json index 1538ac2bd4f..9e744985b6c 100644 --- a/docs/site/package.json +++ b/docs/site/package.json @@ -4,8 +4,8 @@ "private": true, "scripts": { "docusaurus": "docusaurus", - "dev": "docusaurus graphql-to-doc; rm '../content/references/iota-api/iota-graphql/reference/generated.md'; docusaurus start", - "build": "docusaurus graphql-to-doc; rm '../content/references/iota-api/iota-graphql/reference/generated.md'; docusaurus build", + "dev": "docusaurus graphql-to-doc; rm '../content/references/iota-api/iota-graphql/reference/generated.md'; node src/utils/getopenrpcspecs.js; git clean -Xdf ../content/references/layer-2-smart-contracts/; ./scripts/get_wasp_references.sh; docusaurus start", + "build": "docusaurus graphql-to-doc; rm '../content/references/iota-api/iota-graphql/reference/generated.md'; node src/utils/getopenrpcspecs.js; git clean -Xdf ../content/references/layer-2-smart-contracts/; ./scripts/get_wasp_references.sh; docusaurus build", "swizzle": "docusaurus swizzle", "deploy": "docusaurus deploy", "clear": "docusaurus clear", diff --git a/docs/site/scripts/get_wasp_references.sh b/docs/site/scripts/get_wasp_references.sh new file mode 100755 index 00000000000..f784c60a511 --- /dev/null +++ b/docs/site/scripts/get_wasp_references.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +# Create temporaty directory to work in +mkdir tmp +cd tmp + +# Download and copy docs +curl -sL https://s3.eu-central-1.amazonaws.com/files.iota.org/iota-wiki/wasp/1.3/iscmagic.tar.gz | tar xzv +cp -Rv docs/iscmagic/* ../../content/references/layer-2-smart-contracts/magic-contract/ + +curl -sL https://s3.eu-central-1.amazonaws.com/files.iota.org/iota-wiki/wasp/1.3/iscutils.tar.gz | tar xzv +cp -Rv docs/iscutils ../../content/references/layer-2-smart-contracts/ + +# Return to root and cleanup +cd - +rm -rf tmp From 2a5ff800794dbb2116229d75d3de4a114aa46d14 Mon Sep 17 00:00:00 2001 From: Jeroen van den Hout Date: Mon, 10 Jun 2024 00:09:28 +0200 Subject: [PATCH 10/37] fix(docs): add missing components and dependencies --- docs/content/sidebars/developer.js | 6 +- docs/site/package.json | 9 +- .../src/theme/AddToMetaMaskButton/index.tsx | 39 + docs/site/src/theme/ChainId/index.tsx | 21 + docs/site/src/theme/NetworkInfo/index.tsx | 166 +++ docs/site/src/theme/constant.tsx | 194 +++ pnpm-lock.yaml | 1244 ++++++++++++----- 7 files changed, 1302 insertions(+), 377 deletions(-) create mode 100644 docs/site/src/theme/AddToMetaMaskButton/index.tsx create mode 100644 docs/site/src/theme/ChainId/index.tsx create mode 100644 docs/site/src/theme/NetworkInfo/index.tsx create mode 100644 docs/site/src/theme/constant.tsx diff --git a/docs/content/sidebars/developer.js b/docs/content/sidebars/developer.js index 36b5f485bf9..83a5230f34a 100644 --- a/docs/content/sidebars/developer.js +++ b/docs/content/sidebars/developer.js @@ -373,8 +373,8 @@ const developer = [ label: 'Languages & VMs', id: 'guides/developer/layer-2-smart-contracts/getting-started/languages-and-vms', }, - 'getting-started/quick-start', - 'getting-started/compatibility', + 'guides/developer/layer-2-smart-contracts/getting-started/quick-start', + 'guides/developer/layer-2-smart-contracts/getting-started/compatibility', { type: 'doc', label: 'Networks & Chains', @@ -391,7 +391,7 @@ const developer = [ type: 'category', label: 'How To', items: [ - 'how-tos/introduction', + 'guides/developer/layer-2-smart-contracts/how-tos/introduction', { type: 'doc', label: 'Send Funds from L1 to L2', diff --git a/docs/site/package.json b/docs/site/package.json index 9e744985b6c..41b552eb633 100644 --- a/docs/site/package.json +++ b/docs/site/package.json @@ -56,16 +56,21 @@ "react-ui-scrollspy": "^2.3.0", "rehype-katex": "^7.0.0", "remark-math": "^6.0.0", - "tailwindcss": "^3.3.3" + "tailwindcss": "^3.4.4", + "web3": "^4.2.2" }, "devDependencies": { "@babel/plugin-transform-react-jsx": "^7.24.7", "@docusaurus/module-type-aliases": "3.4.0", "@docusaurus/tsconfig": "3.4.0", "@docusaurus/types": "3.4.0", - "@types/react": "^18.2.15", + "@metamask/providers": "^10.2.1", + "@types/react": "^18.3.3", "typescript": "^5.3.3" }, + "resolutions": { + "graphql": "^16.8.1" + }, "browserslist": { "production": [ ">0.5%", diff --git a/docs/site/src/theme/AddToMetaMaskButton/index.tsx b/docs/site/src/theme/AddToMetaMaskButton/index.tsx new file mode 100644 index 00000000000..dc10cf4cc43 --- /dev/null +++ b/docs/site/src/theme/AddToMetaMaskButton/index.tsx @@ -0,0 +1,39 @@ +import React from 'react'; +import type { MetaMaskInpageProvider } from '@metamask/providers'; +import { NetworkProps } from '../constant'; + +declare global { + interface Window { + ethereum?: MetaMaskInpageProvider; + } +} + +export function AddToMetaMaskButton(props: NetworkProps) { + async function addNetwork() { + if (!window.ethereum) { + alert( + 'MetaMask is not installed. Please install MetaMask and try again.', + ); + return; + } + + try { + await window.ethereum.request({ + method: 'wallet_addEthereumChain', + params: [props.evm], + }); + } catch (error) { + console.error(error); + console.log('Error adding network: ' + error.message); + } + } + + return ( + + ); +} diff --git a/docs/site/src/theme/ChainId/index.tsx b/docs/site/src/theme/ChainId/index.tsx new file mode 100644 index 00000000000..5ba10746a8e --- /dev/null +++ b/docs/site/src/theme/ChainId/index.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { useEffect, useState } from 'react'; +import { Web3 } from 'web3'; + +interface ChainIdProps { + url: string; +} + +export function ChainId(props: ChainIdProps) { + const [value, setValue] = useState(null); + + useEffect(() => { + const web3 = new Web3(props.url); + web3.eth + .getChainId() + .then((chainId) => setValue(chainId.toString())) + .catch((error) => setValue(`Error: ${error.message}`)); + }, []); + + return <>{value}; +} diff --git a/docs/site/src/theme/NetworkInfo/index.tsx b/docs/site/src/theme/NetworkInfo/index.tsx new file mode 100644 index 00000000000..3cf243df9f0 --- /dev/null +++ b/docs/site/src/theme/NetworkInfo/index.tsx @@ -0,0 +1,166 @@ +import React from 'react'; +import { ChainId } from '../ChainId'; +import { NetworkProps } from '../constant'; +import CodeBlock from '@theme/CodeBlock'; +import Admonition from '@theme/Admonition'; + +function L1(props: NetworkProps) { + return ( + + + + + + + + + + + + + + + + + + + + + + + {props.faucet && ( + + + + + )} + +
Base Token{props.baseToken}
Protocol{props.protocol}
HTTP REST API + {props.httpRestApi} +
Event API + {props.eventApi} +
Permanode API + {props.permaNodeApi} +
Faucet + + {props.faucet} + +
+ ); +} + +function Evm(props: NetworkProps) { + return ( + + + + + + + + + + + + + + + + + + + {props.evmCustom.blastApiUrls && ( + + + + + )} + + + + + + + + + + + + + +
Base Token{props.baseToken}
ProtocolISC / EVM
Chain ID + +
RPC URL + {props.evm.rpcUrls.map((url, index) => ( + {url} + ))} +
+ + Blast API provides highly + scalable fault-tolerant API endpoints. + + + {props.evmCustom.blastApiUrls.map((object, index) => + typeof object === 'string' ? ( + {object as string} + ) : ( + + {' '} + {Object.values(object)[0]}{' '} + + ), + )} +
Explorer + + {props.evm.blockExplorerUrls[0]} + +
+ {props.evmCustom.toolkit.hasFaucet ? 'Toolkit & Faucet' : 'Toolkit'} + + + {props.evmCustom.toolkit.url} + +
WASP API + {props.evmCustom.api} +
+ ); +} + +function EvmCustom(props: NetworkProps) { + return ( + + + + + + + + + + + +
Chain Address + + {props.evmCustom.chainAddress} + +
Alias ID{props.evmCustom.aliasId}
+ ); +} + +export default { + L1, + Evm, + EvmCustom, +}; diff --git a/docs/site/src/theme/constant.tsx b/docs/site/src/theme/constant.tsx new file mode 100644 index 00000000000..78099fb9e73 --- /dev/null +++ b/docs/site/src/theme/constant.tsx @@ -0,0 +1,194 @@ +export const Networks = { + iota: { + baseToken: 'IOTA Token', + protocol: 'Stardust', + httpRestApi: 'https://api.stardust-mainnet.iotaledger.net', + eventApi: 'wss://api.stardust-mainnet.iotaledger.net:443 (MQTT 3.1, /mqtt)', + permaNodeApi: 'https://chronicle.stardust-mainnet.iotaledger.net', + explorer: 'https://explorer.iota.org/mainnet', + evm: { + chainId: '0x2276', + chainName: 'IOTA EVM', + nativeCurrency: { + name: 'IOTA', + symbol: 'IOTA', + decimals: 18, + }, + rpcUrls: [ + 'https://json-rpc.evm.iotaledger.net', + 'wss://ws.json-rpc.evm.iotaledger.net', + ], + blockExplorerUrls: ['https://explorer.evm.iota.org'], + }, + evmCustom: { + chainAddress: + 'iota1pzt3mstq6khgc3tl0mwuzk3eqddkryqnpdxmk4nr25re2466uxwm28qqxu5', + aliasId: + '0x971dc160d5ae8c457f7eddc15a39035b6190130b4dbb5663550795575ae19db5', + blastApiUrls: [ + 'https://iota-mainnet-evm.public.blastapi.io', + 'wss://iota-mainnet-evm.public.blastapi.io', + { + 'Archive RPC': + 'https://iota-mainnet-evm.blastapi.io/e7596858-fc63-4a54-8727-b885a2af4ec8', + }, + ], + toolkit: { + url: 'https://evm-toolkit.evm.iotaledger.net', + hasFaucet: false, + }, + api: 'https://api.evm.iotaledger.net', + }, + }, + iota_2_testnet: { + baseToken: 'Testnet Token (no value)', + protocol: 'IOTA 2.0', + httpRestApi: 'https://api.nova-testnet.iotaledger.net/', + eventApi: 'wss://api.nova-testnet.iotaledger.net:443 (MQTT 3.1, /mqtt)', + permaNodeApi: 'https://chronicle.nova-testnet.iotaledger.net', + explorer: 'https://explorer.iota.org/iota2-testnet', + faucet: 'https://faucet.nova-testnet.iotaledger.net', + }, + iota_testnet: { + baseToken: 'Testnet Token (no value)', + protocol: 'Stardust', + httpRestApi: 'https://api.testnet.iotaledger.net', + eventApi: 'wss://api.testnet.iotaledger.net:443 (MQTT 3.1, /mqtt)', + permaNodeApi: 'https://chronicle.testnet.iotaledger.net', + faucet: 'https://faucet.testnet.iotaledger.net', + explorer: 'https://explorer.iota.org/iota-testnet', + evm: { + chainId: '0x433', + chainName: 'IOTA EVM Testnet', + nativeCurrency: { + name: 'IOTA', + symbol: 'IOTA', + decimals: 18, + }, + rpcUrls: [ + 'https://json-rpc.evm.testnet.iotaledger.net', + 'wss://ws.json-rpc.evm.testnet.iotaledger.net', + ], + blockExplorerUrls: ['https://explorer.evm.testnet.iotaledger.net'], + }, + evmCustom: { + chainAddress: + 'tst1pzxsrr7apqkdzz633dyntmvxwtyvk029p39te5j0m33q6946h7akzv663zu', + aliasId: + '0x8d018fdd082cd10b518b4935ed8672c8cb3d450c4abcd24fdc620d16babfbb61', + blastApiUrls: [ + 'https://iota-testnet-evm.public.blastapi.io', + 'wss://iota-testnet-evm.public.blastapi.io', + { + 'Archive RPC': + 'https://iota-testnet-evm.blastapi.io/e7596858-fc63-4a54-8727-b885a2af4ec8', + }, + ], + toolkit: { + url: 'https://evm-toolkit.evm.testnet.iotaledger.net', + hasFaucet: false, + }, + api: 'https://api.evm.testnet.iotaledger.net', + }, + }, + shimmer: { + baseToken: 'Shimmer Token', + protocol: 'Stardust', + httpRestApi: 'https://api.shimmer.network', + eventApi: 'wss://api.shimmer.network:443/api/mqtt/v1 (MQTT 3.1)', + permaNodeApi: 'https://chronicle.shimmer.network', + explorer: 'https://explorer.shimmer.network/shimmer', + evm: { + chainId: '0x94', + chainName: 'ShimmerEVM', + nativeCurrency: { + name: 'Shimmer', + symbol: 'SMR', + decimals: 18, + }, + rpcUrls: [ + 'https://json-rpc.evm.shimmer.network', + 'wss://ws.json-rpc.evm.shimmer.network', + ], + blockExplorerUrls: ['https://explorer.evm.shimmer.network/'], + }, + evmCustom: { + chainAddress: + 'smr1prxvwqvwf7nru5q5xvh5thwg54zsm2y4wfnk6yk56hj3exxkg92mx20wl3s', + aliasId: + '0xccc7018e4fa63e5014332f45ddc8a5450da89572676d12d4d5e51c98d64155b3', + toolkit: { + url: 'https://evm-toolkit.evm.shimmer.network', + hasFaucet: false, + }, + api: 'https://api.evm.shimmer.network', + }, + }, + shimmer_testnet: { + baseToken: 'Testnet Token (no value)', + protocol: 'Stardust', + httpRestApi: 'https://api.testnet.shimmer.network', + eventApi: 'wss://api.testnet.shimmer.network:443/api/mqtt/v1 (MQTT 3.1)', + permaNodeApi: 'https://chronicle.testnet.shimmer.network', + faucet: 'https://faucet.testnet.shimmer.network', + explorer: 'https://explorer.shimmer.network/shimmer-testnet', + evm: { + chainId: '0x431', + chainName: 'ShimmerEVM Testnet', + nativeCurrency: { + name: 'Shimmer', + symbol: 'SMR', + decimals: 18, + }, + rpcUrls: ['https://json-rpc.evm.testnet.shimmer.network'], + blockExplorerUrls: ['https://explorer.evm.testnet.shimmer.network/'], + }, + evmCustom: { + chainAddress: + 'rms1ppp00k5mmd2m8my8ukkp58nd3rskw6rx8l09aj35984k74uuc5u2cywn3ex', + aliasId: + '0x42f7da9bdb55b3ec87e5ac1a1e6d88e16768663fde5eca3429eb6f579cc538ac', + toolkit: { + url: 'https://evm-toolkit.evm.testnet.shimmer.network', + hasFaucet: true, + }, + api: 'https://api.evm.testnet.shimmer.network', + }, + }, +}; + +export interface Toolkit { + url: string; + hasFaucet: boolean; +} + +export interface AddEthereumChainParameter { + chainId: string; // A 0x-prefixed hexadecimal string + chainName: string; + nativeCurrency?: { + name: string; + symbol: string; // 2-6 characters long + decimals: number; + }; + rpcUrls?: string[]; + blockExplorerUrls?: string[]; + iconUrls?: string[]; // Currently ignored. +} + +export interface NetworkProps { + baseToken: string; + protocol: string; + httpRestApi: string; + eventApi: string; + permaNodeApi: string; + faucet?: string; + explorer: string; + evm: AddEthereumChainParameter; + evmCustom: { + chainAddress: string; + aliasId: string; + blastApiUrls?: Array; + toolkit?: Toolkit; + api?: string; + }; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 272a0e1c0a3..4d17767591b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -132,7 +132,7 @@ importers: devDependencies: '@nestjs/cli': specifier: ^10.0.0 - version: 10.3.2(@swc/core@1.3.92) + version: 10.3.2(@swc/core@1.3.92(@swc/helpers@0.5.5)) '@nestjs/schematics': specifier: ^10.0.0 version: 10.1.1(chokidar@3.6.0)(typescript@5.3.3) @@ -168,7 +168,7 @@ importers: version: 5.1.3(@types/eslint@8.37.0)(eslint-config-prettier@9.1.0(eslint@8.45.0))(eslint@8.45.0)(prettier@3.3.2) jest: specifier: ^29.5.0 - version: 29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + version: 29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) prettier: specifier: ^3.3.1 version: 3.3.2 @@ -180,13 +180,13 @@ importers: version: 6.3.4 ts-jest: specifier: ^29.1.0 - version: 29.1.3(@babel/core@7.23.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(jest@29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)))(typescript@5.3.3) + version: 29.1.3(@babel/core@7.23.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(jest@29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)))(typescript@5.3.3) ts-loader: specifier: ^9.4.4 - version: 9.4.4(typescript@5.3.3)(webpack@5.90.1(@swc/core@1.3.92)) + version: 9.4.4(typescript@5.3.3)(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) ts-node: specifier: ^10.9.1 - version: 10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3) + version: 10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3) tsconfig-paths: specifier: ^4.2.0 version: 4.2.0 @@ -250,25 +250,25 @@ importers: devDependencies: '@headlessui/tailwindcss': specifier: ^0.1.3 - version: 0.1.3(tailwindcss@3.3.3(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.3.3))) + version: 0.1.3(tailwindcss@3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3))) '@tailwindcss/aspect-ratio': specifier: ^0.4.2 - version: 0.4.2(tailwindcss@3.3.3(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.3.3))) + version: 0.4.2(tailwindcss@3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3))) '@tailwindcss/forms': specifier: ^0.5.4 - version: 0.5.4(tailwindcss@3.3.3(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.3.3))) + version: 0.5.4(tailwindcss@3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3))) '@types/react': specifier: ^18.2.15 version: 18.2.15 '@vanilla-extract/vite-plugin': specifier: ^3.9.0 - version: 3.9.0(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.3.3))(vite@4.4.4(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0)) + version: 3.9.0(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3))(vite@4.4.4(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0)) postcss: specifier: ^8.4.31 version: 8.4.31 tailwindcss: specifier: ^3.3.3 - version: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + version: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) typescript: specifier: ^5.3.3 version: 5.3.3 @@ -500,7 +500,7 @@ importers: version: 2.0.0 tailwindcss: specifier: ^3.3.3 - version: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + version: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) tsconfig-paths: specifier: ^4.2.0 version: 4.2.0 @@ -609,7 +609,7 @@ importers: version: 7.1.0 tailwindcss: specifier: ^3.3.3 - version: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + version: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) typescript: specifier: ^5.3.3 version: 5.3.3 @@ -658,7 +658,7 @@ importers: version: 7.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.4)(typescript@5.4.5)(vite@4.4.11(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0)) '@storybook/test': specifier: ^8.1.11 - version: 8.1.11(@jest/globals@29.7.0)(@types/jest@29.5.3)(jest@29.7.0(@types/node@20.4.2)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)))(vitest@0.33.0(sass@1.63.6)(terser@5.31.0)) + version: 8.1.11(@jest/globals@29.7.0)(@types/jest@29.5.3)(jest@29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)))(vitest@0.33.0(@vitest/ui@0.33.0)(happy-dom@10.5.1)(jsdom@23.0.0)(sass@1.63.6)(terser@5.31.0)) '@types/lodash.merge': specifier: ^4.6.9 version: 4.6.9 @@ -688,7 +688,7 @@ importers: version: 4.0.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) tailwindcss: specifier: ^3.3.3 - version: 3.3.3(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)) + version: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)) typescript: specifier: ^5.3.3 version: 5.4.5 @@ -950,7 +950,7 @@ importers: version: 0.10.1 '@types/webpack': specifier: ^5.28.1 - version: 5.28.1(@swc/core@1.3.92)(webpack-cli@5.0.1(webpack@5.79.0)) + version: 5.28.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0)) '@types/zxcvbn': specifier: ^4.4.1 version: 4.4.1 @@ -959,19 +959,19 @@ importers: version: 4.0.3(vite@4.4.4(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0)) copy-webpack-plugin: specifier: ^11.0.0 - version: 11.0.0(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)) + version: 11.0.0(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))) cross-env: specifier: ^7.0.3 version: 7.0.3 css-loader: specifier: ^6.7.3 - version: 6.7.3(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)) + version: 6.7.3(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))) dotenv: specifier: ^16.4.5 version: 16.4.5 eslint-webpack-plugin: specifier: ^4.0.1 - version: 4.0.1(eslint@8.57.0)(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)) + version: 4.0.1(eslint@8.57.0)(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))) git-rev-sync: specifier: ^3.0.2 version: 3.0.2 @@ -980,10 +980,10 @@ importers: version: 10.5.1 html-webpack-plugin: specifier: ^5.5.3 - version: 5.5.3(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)) + version: 5.5.3(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))) mini-css-extract-plugin: specifier: ^2.7.6 - version: 2.7.6(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)) + version: 2.7.6(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))) onchange: specifier: ^7.1.0 version: 7.1.0 @@ -992,7 +992,7 @@ importers: version: 8.4.31 postcss-loader: specifier: ^7.3.3 - version: 7.3.3(postcss@8.4.31)(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)) + version: 7.3.3(postcss@8.4.31)(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))) postcss-preset-env: specifier: ^9.0.0 version: 9.0.0(postcss@8.4.31) @@ -1001,19 +1001,19 @@ importers: version: 1.63.6 sass-loader: specifier: ^13.3.2 - version: 13.3.2(sass@1.63.6)(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)) + version: 13.3.2(sass@1.63.6)(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))) tailwindcss: specifier: ^3.3.3 - version: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + version: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) tailwindcss-animate: specifier: ^1.0.6 - version: 1.0.6(tailwindcss@3.3.3(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.3.3))) + version: 1.0.6(tailwindcss@3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3))) ts-loader: specifier: ^9.4.4 - version: 9.4.4(typescript@5.3.3)(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)) + version: 9.4.4(typescript@5.3.3)(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))) ts-node: specifier: ^10.9.1 - version: 10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3) + version: 10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3) tsconfig-paths: specifier: ^4.2.0 version: 4.2.0 @@ -1031,10 +1031,10 @@ importers: version: 0.33.0(@vitest/ui@0.33.0)(happy-dom@10.5.1)(jsdom@23.0.0)(sass@1.63.6)(terser@5.31.0) web-ext: specifier: ^7.6.2 - version: 7.6.2(body-parser@1.20.2)(express@4.18.2) + version: 7.6.2(body-parser@1.20.2)(express@4.19.2) webpack: specifier: ^5.79.0 - version: 5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1) + version: 5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0)) webpack-cli: specifier: ^5.0.1 version: 5.0.1(webpack@5.79.0) @@ -1064,7 +1064,7 @@ importers: version: 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next: specifier: 14.2.3 - version: 14.2.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.63.6) + version: 14.2.3(@playwright/test@1.36.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.63.6) react: specifier: ^18.3.1 version: 18.3.1 @@ -1089,7 +1089,7 @@ importers: version: 8.4.31 tailwindcss: specifier: ^3.3.3 - version: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + version: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1129,7 +1129,7 @@ importers: devDependencies: '@headlessui/tailwindcss': specifier: ^0.1.3 - version: 0.1.3(tailwindcss@3.3.3(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.3.3))) + version: 0.1.3(tailwindcss@3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3))) '@types/react': specifier: ^18.2.15 version: 18.2.15 @@ -1147,7 +1147,7 @@ importers: version: 8.4.31 tailwindcss: specifier: ^3.3.3 - version: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + version: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1241,7 +1241,7 @@ importers: version: link:../../sdk/typescript '@tailwindcss/forms': specifier: ^0.5.4 - version: 0.5.4(tailwindcss@3.3.3(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.3.3))) + version: 0.5.4(tailwindcss@3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3))) '@types/react': specifier: ^18.2.15 version: 18.2.15 @@ -1259,10 +1259,10 @@ importers: version: 8.4.31 tailwindcss: specifier: ^3.3.3 - version: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + version: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) tailwindcss-animate: specifier: ^1.0.6 - version: 1.0.6(tailwindcss@3.3.3(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.3.3))) + version: 1.0.6(tailwindcss@3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3))) typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1308,7 +1308,7 @@ importers: version: 8.4.31 tailwindcss: specifier: ^3.3.3 - version: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + version: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1326,22 +1326,22 @@ importers: version: 3.6.0(@algolia/client-search@4.23.3)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/core': specifier: 3.4.0 - version: 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + version: 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) '@docusaurus/preset-classic': specifier: 3.4.0 - version: 3.4.0(@algolia/client-search@4.23.3)(@types/react@18.3.3)(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + version: 3.4.0(@algolia/client-search@4.23.3)(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/react@18.3.3)(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) '@docusaurus/remark-plugin-npm2yarn': specifier: ^3.4.0 version: 3.4.0 '@docusaurus/theme-common': specifier: ^3.4.0 - version: 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + version: 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) '@docusaurus/theme-mermaid': specifier: ^3.4.0 - version: 3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + version: 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) '@docusaurus/theme-search-algolia': specifier: ^3.4.0 - version: 3.4.0(@algolia/client-search@4.23.3)(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + version: 3.4.0(@algolia/client-search@4.23.3)(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/react@18.3.3)(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) '@emotion/react': specifier: ^11.11.4 version: 11.11.4(@types/react@18.3.3)(react@18.3.1) @@ -1350,7 +1350,7 @@ importers: version: 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) '@graphql-markdown/docusaurus': specifier: ^1.24.1 - version: 1.24.2(@docusaurus/logger@3.4.0)(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(graphql-config@5.0.3(@types/node@20.4.2)(graphql@16.8.1))(graphql@16.8.1)(prettier@3.3.2)(typescript@5.4.5) + version: 1.24.2(@docusaurus/logger@3.4.0)(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(graphql-config@5.0.3(@types/node@20.4.2)(graphql@16.8.1))(graphql@16.8.1)(prettier@3.3.2)(typescript@5.4.5) '@graphql-tools/graphql-file-loader': specifier: ^8.0.1 version: 8.0.1(graphql@16.8.1) @@ -1433,23 +1433,29 @@ importers: specifier: ^6.0.0 version: 6.0.0 tailwindcss: - specifier: ^3.3.3 - version: 3.4.4(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)) + specifier: ^3.4.4 + version: 3.4.4(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)) + web3: + specifier: ^4.2.2 + version: 4.11.0(typescript@5.4.5)(zod@3.21.4) devDependencies: '@babel/plugin-transform-react-jsx': specifier: ^7.24.7 version: 7.24.7(@babel/core@7.23.9) '@docusaurus/module-type-aliases': specifier: 3.4.0 - version: 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/tsconfig': specifier: 3.4.0 version: 3.4.0 '@docusaurus/types': specifier: 3.4.0 - version: 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@metamask/providers': + specifier: ^10.2.1 + version: 10.2.1 '@types/react': - specifier: ^18.2.15 + specifier: ^18.3.3 version: 18.3.3 typescript: specifier: ^5.3.3 @@ -1717,7 +1723,7 @@ importers: version: 2.3.0(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0) '@vanilla-extract/vite-plugin': specifier: ^3.9.0 - version: 3.9.0(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.3.3))(vite@4.4.11(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0)) + version: 3.9.0(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3))(vite@4.4.11(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0)) dotenv: specifier: ^16.4.5 version: 16.4.5 @@ -1815,7 +1821,7 @@ importers: version: 16.4.5 ts-node: specifier: ^10.9.1 - version: 10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3) + version: 10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3) typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2079,6 +2085,9 @@ packages: '@adobe/css-tools@4.4.0': resolution: {integrity: sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==} + '@adraffy/ens-normalize@1.10.1': + resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==} + '@algolia/autocomplete-core@1.9.3': resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==} @@ -4286,6 +4295,16 @@ packages: resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@ethereumjs/rlp@4.0.1': + resolution: {integrity: sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==} + engines: {node: '>=14'} + hasBin: true + + '@ethereumjs/rlp@5.0.2': + resolution: {integrity: sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA==} + engines: {node: '>=18'} + hasBin: true + '@faker-js/faker@8.0.2': resolution: {integrity: sha512-Uo3pGspElQW91PCvKSIAXoEgAUlRnH29sX2/p89kg7sP1m2PzCufHINd0FhTXQf6DYGiUlVncdSPa2F9wxed2A==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0, npm: '>=6.14.13'} @@ -4935,6 +4954,21 @@ packages: resolution: {integrity: sha512-FBvah1mPte5HudQdkgqAh2+Zc75T9kYxey+dCtHIj9gKohkHDcIA1bTOPLk0bBH+6PnOzYNPG8devvH04GOmPA==} engines: {node: '>=14.0.0'} + '@metamask/object-multiplex@1.3.0': + resolution: {integrity: sha512-czcQeVYdSNtabd+NcYQnrM69MciiJyd1qvKH8WM2Id3C0ZiUUX5Xa/MK+/VUk633DBhVOwdNzAKIQ33lGyA+eQ==} + engines: {node: '>=12.0.0'} + + '@metamask/providers@10.2.1': + resolution: {integrity: sha512-p2TXw2a1Nb8czntDGfeIYQnk4LLVbd5vlcb3GY//lylYlKdSqp+uUTegCvxiFblRDOT68jsY8Ib1VEEzVUOolA==} + engines: {node: '>=14.0.0'} + + '@metamask/safe-event-emitter@2.0.0': + resolution: {integrity: sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q==} + + '@metamask/safe-event-emitter@3.1.1': + resolution: {integrity: sha512-ihb3B0T/wJm1eUuArYP4lCTSEoZsClHhuWyfo/kMX3m/odpqNcPfsz5O2A3NT7dXCAgWPGDQGPqygCpgeniKMw==} + engines: {node: '>=12.0.0'} + '@microsoft/api-extractor-model@7.28.13': resolution: {integrity: sha512-39v/JyldX4MS9uzHcdfmjjfS6cYGAoXV+io8B5a338pkHiSt+gy2eXQ0Q7cGFJ7quSa1VqqlMdlPrB6sLR/cAw==} @@ -5201,10 +5235,17 @@ packages: '@noble/curves@1.1.0': resolution: {integrity: sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==} + '@noble/curves@1.4.2': + resolution: {integrity: sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==} + '@noble/hashes@1.3.1': resolution: {integrity: sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==} engines: {node: '>= 16'} + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -6270,12 +6311,21 @@ packages: '@scure/base@1.1.1': resolution: {integrity: sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==} + '@scure/base@1.1.7': + resolution: {integrity: sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g==} + '@scure/bip32@1.3.1': resolution: {integrity: sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==} + '@scure/bip32@1.4.0': + resolution: {integrity: sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==} + '@scure/bip39@1.2.1': resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==} + '@scure/bip39@1.3.0': + resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==} + '@sentry-internal/tracing@7.59.2': resolution: {integrity: sha512-02gteChV/lMobWU06VlITq+myEWk0MzhnDCm8n/DMigB47I9HkWZFAJ+CYG6Ns0rTL+3+/c2V0bPyQkZwIC+Sg==} engines: {node: '>=8'} @@ -7172,6 +7222,9 @@ packages: '@types/chai@4.3.5': resolution: {integrity: sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==} + '@types/chrome@0.0.136': + resolution: {integrity: sha512-XDEiRhLkMd+SB7Iw3ZUIj/fov3wLd4HyTdLltVszkgl1dBfc3Rb7oPMVZ2Mz2TLqnF7Ow+StbR8E7r9lqpb4DA==} + '@types/connect-history-api-fallback@1.5.4': resolution: {integrity: sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==} @@ -7274,6 +7327,12 @@ packages: '@types/express@4.17.17': resolution: {integrity: sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==} + '@types/filesystem@0.0.36': + resolution: {integrity: sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA==} + + '@types/filewriter@0.0.33': + resolution: {integrity: sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==} + '@types/find-cache-dir@3.2.1': resolution: {integrity: sha512-frsJrz2t/CeGifcu/6uRo4b+SzAwT4NYCVPu1GN8IB9XTzrpPkGuV0tmh9mN+/L0PklAlsC3u5Fxt0ju00LXIw==} @@ -7292,6 +7351,9 @@ packages: '@types/gtag.js@0.0.12': resolution: {integrity: sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==} + '@types/har-format@1.2.15': + resolution: {integrity: sha512-RpQH4rXLuvTXKR0zqHq3go0RVXYv/YVqv4TnPH95VbwUxZdQlK1EtcMvQvMpDngHbt13Csh9Z4qT9AbkiQH5BA==} + '@types/hast@2.3.10': resolution: {integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==} @@ -7544,6 +7606,9 @@ packages: '@types/webpack@5.28.1': resolution: {integrity: sha512-qw1MqGZclCoBrpiSe/hokSgQM/su8Ocpl3L/YHE0L6moyaypg4+5F7Uzq7NgaPKPxUxUbQ4fLPLpDWdR27bCZw==} + '@types/ws@8.5.3': + resolution: {integrity: sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==} + '@types/ws@8.5.9': resolution: {integrity: sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==} @@ -8127,6 +8192,15 @@ packages: '@zxing/text-encoding@0.9.0': resolution: {integrity: sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==} + abitype@0.7.1: + resolution: {integrity: sha512-VBkRHTDZf9Myaek/dO3yMmOzB/y2s3Zo6nVU7yaw1G+TvCHAjwaJzNGN9yo4K5D8bU/VZXKP1EJpRhFr862PlQ==} + peerDependencies: + typescript: '>=4.9.4' + zod: ^3 >=3.19.1 + peerDependenciesMeta: + zod: + optional: true + abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} @@ -9374,6 +9448,11 @@ packages: typescript: optional: true + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + create-jest@29.7.0: resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -9396,6 +9475,9 @@ packages: cross-fetch@3.1.8: resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} + cross-fetch@4.0.0: + resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} + cross-inspect@1.0.0: resolution: {integrity: sha512-4PFfn4b5ZN6FMNGSZlyb7wUhuN8wvj8t/VQHZdM4JsDcruGJ8L2kf9zao98QIrBPFCpdk27qst/AGTl7pL3ypQ==} engines: {node: '>=16.0.0'} @@ -9933,6 +10015,9 @@ packages: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + detect-browser@5.3.0: + resolution: {integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==} + detect-indent@6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} @@ -10579,6 +10664,12 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} + eth-rpc-errors@4.0.3: + resolution: {integrity: sha512-Z3ymjopaoft7JDoxZcEb3pwdGh7yiYMhOwm2doUt6ASXlMavpNlK6Cre0+IMl2VSGyEU9rkiperQhp5iRxn5Pg==} + + ethereum-cryptography@2.2.1: + resolution: {integrity: sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==} + eval@0.1.8: resolution: {integrity: sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==} engines: {node: '>= 0.8'} @@ -10642,6 +10733,10 @@ packages: extendable-error@0.1.7: resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + extension-port-stream@2.1.1: + resolution: {integrity: sha512-qknp5o5rj2J9CRKfVB8KJr+uXQlrojNZzdESUPhKYLXf97TPcGf6qWWKmpsNNtUyOdzFhab1ON0jzouNxHHvow==} + engines: {node: '>=12.0.0'} + external-editor@3.1.0: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} engines: {node: '>=4'} @@ -10669,6 +10764,9 @@ packages: fast-decode-uri-component@1.0.1: resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} + fast-deep-equal@2.0.1: + resolution: {integrity: sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -12402,6 +12500,14 @@ packages: json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-rpc-engine@6.1.0: + resolution: {integrity: sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ==} + engines: {node: '>=10.0.0'} + + json-rpc-middleware-stream@4.2.3: + resolution: {integrity: sha512-4iFb0yffm5vo3eFKDbQgke9o17XBcLQ2c3sONrXSbcOLzP8LTojqo8hRGVgtJShhm5q4ZDSNq039fAx9o65E1w==} + engines: {node: '>=14.0.0'} + json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -17067,12 +17173,95 @@ packages: web-worker@1.3.0: resolution: {integrity: sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==} + web3-core@4.5.0: + resolution: {integrity: sha512-Q8LIAqmF7vkRydBPiU+OC7wI44nEU6JEExolFaOakqrjMtQ1CWFHRUQMNJRDsk5bRirjyShuAsuqLeYByvvXhg==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-errors@1.2.0: + resolution: {integrity: sha512-58Kczou5zyjcm9LuSs5Hrm6VrG8t9p2J8X0yGArZrhKNPZL66gMGkOUpPx+EopE944Sk4yE+Q25hKv4H5BH+kA==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth-abi@4.2.3: + resolution: {integrity: sha512-rPVwTn0O1CzbtfXwEfIjUP0W5Y7u1OFjugwKpSqJzPQE6+REBg6OELjomTGZBu+GThxHnv0rp15SOxvqp+tyXA==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth-accounts@4.1.3: + resolution: {integrity: sha512-61Nb7xCXy6Vw/6xUZMM5ITtXetXmaP0F8oKRxika4GO4fRfKZLAwBZtshMyrdAORPZYq77ENiqXJVU+hTmtUaQ==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth-contract@4.6.0: + resolution: {integrity: sha512-mgQ/WUUlgW9BVKKVGU/Q7KrQEbEGI98h8ppox7fT964wY9ITFMDuRCvYk50WTWnFMdjFtOBqt1xRJ0+B1ekCHg==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth-ens@4.4.0: + resolution: {integrity: sha512-DeyVIS060hNV9g8dnTx92syqvgbvPricE3MerCxe/DquNZT3tD8aVgFfq65GATtpCgDDJffO2bVeHp3XBemnSQ==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth-iban@4.0.7: + resolution: {integrity: sha512-8weKLa9KuKRzibC87vNLdkinpUE30gn0IGY027F8doeJdcPUfsa4IlBgNC4k4HLBembBB2CTU0Kr/HAOqMeYVQ==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth-personal@4.0.8: + resolution: {integrity: sha512-sXeyLKJ7ddQdMxz1BZkAwImjqh7OmKxhXoBNF3isDmD4QDpMIwv/t237S3q4Z0sZQamPa/pHebJRWVuvP8jZdw==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth@4.8.1: + resolution: {integrity: sha512-pQI46LIaqB1Nz2DcslxgbN+E5Coc/BCO2MEwcFJgjc8yrGHoY5rjYlucNozftuluVCcK8Jen7c2uNOIiIdewmQ==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-net@4.1.0: + resolution: {integrity: sha512-WWmfvHVIXWEoBDWdgKNYKN8rAy6SgluZ0abyRyXOL3ESr7ym7pKWbfP4fjApIHlYTh8tNqkrdPfM4Dyi6CA0SA==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-providers-http@4.1.0: + resolution: {integrity: sha512-6qRUGAhJfVQM41E5t+re5IHYmb5hSaLc02BE2MaRQsz2xKA6RjmHpOA5h/+ojJxEpI9NI2CrfDKOAgtJfoUJQg==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-providers-ipc@4.0.7: + resolution: {integrity: sha512-YbNqY4zUvIaK2MHr1lQFE53/8t/ejHtJchrWn9zVbFMGXlTsOAbNoIoZWROrg1v+hCBvT2c9z8xt7e/+uz5p1g==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-providers-ws@4.0.8: + resolution: {integrity: sha512-goJdgata7v4pyzHRsg9fSegUG4gVnHZSHODhNnn6J93ykHkBI1nz4fjlGpcQLUMi4jAMz6SHl9Ibzs2jj9xqPw==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-rpc-methods@1.3.0: + resolution: {integrity: sha512-/CHmzGN+IYgdBOme7PdqzF+FNeMleefzqs0LVOduncSaqsppeOEoskLXb2anSpzmQAP3xZJPaTrkQPWSJMORig==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-rpc-providers@1.0.0-rc.1: + resolution: {integrity: sha512-N7AgGB+ilKPFQohnlI1vNHWmQ5Wh5vlGdYKWCWJc9kisKxxGtOsqN3W8tOj6/898sHZIXU9i/IAOyreGDIybmw==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-types@1.7.0: + resolution: {integrity: sha512-nhXxDJ7a5FesRw9UG5SZdP/C/3Q2EzHGnB39hkAV+YGXDMgwxBXFWebQLfEzZzuArfHnvC0sQqkIHNwSKcVjdA==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-utils@4.3.1: + resolution: {integrity: sha512-kGwOk8FxOLJ9DQC68yqNQc7AzN+k9YDLaW+ZjlAXs3qORhf8zXk5SxWAAGLbLykMs3vTeB0FTb1Exut4JEYfFA==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-validator@2.0.6: + resolution: {integrity: sha512-qn9id0/l1bWmvH4XfnG/JtGKKwut2Vokl6YXP5Kfg424npysmtRLe9DgiNBM9Op7QL/aSiaA0TVXibuIuWcizg==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3@4.11.0: + resolution: {integrity: sha512-VBk09UsKyDn8e+NA7UyuF4iOnf8n7GQ45aM+414J8/R1wa2IA3kLUvN3yf9v56EDOV8IGknVPAVaTu/J4W+ShQ==} + engines: {node: '>=14.0.0', npm: '>=6.12.0'} + webcrypto-core@1.7.8: resolution: {integrity: sha512-eBR98r9nQXTqXt/yDRtInszPMjTaSAMJAFDg2AHsgrnczawT1asx9YNBX6k5p+MekbPF4+s/UJJrr88zsTqkSg==} + webextension-polyfill-ts@0.25.0: + resolution: {integrity: sha512-ikQhwwHYkpBu00pFaUzIKY26I6L87DeRI+Q6jBT1daZUNuu8dSrg5U9l/ZbqdaQ1M/TTSPKeAa3kolP5liuedw==} + deprecated: This project has moved to @types/webextension-polyfill + webextension-polyfill@0.10.0: resolution: {integrity: sha512-c5s35LgVa5tFaHhrZDnr3FpQpjj1BB+RXhLTYUxGqBVN460HkbM8TBtEqdXWbpTKfzwCcjAZVF7zXCYSKtcp9g==} + webextension-polyfill@0.7.0: + resolution: {integrity: sha512-su48BkMLxqzTTvPSE1eWxKToPS2Tv5DLGxKexLEVpwFd6Po6N8hhSLIvG6acPAg7qERoEaDL+Y5HQJeJeml5Aw==} + webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -17510,6 +17699,8 @@ snapshots: '@adobe/css-tools@4.4.0': {} + '@adraffy/ens-normalize@1.10.1': {} + '@algolia/autocomplete-core@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)': dependencies: '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3) @@ -20186,7 +20377,7 @@ snapshots: transitivePeerDependencies: - '@algolia/client-search' - '@docusaurus/core@3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': + '@docusaurus/core@3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': dependencies: '@babel/core': 7.23.9 '@babel/generator': 7.23.6 @@ -20200,12 +20391,12 @@ snapshots: '@babel/traverse': 7.23.9 '@docusaurus/cssnano-preset': 3.4.0 '@docusaurus/logger': 3.4.0 - '@docusaurus/mdx-loader': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5) - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) + '@docusaurus/mdx-loader': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5) + '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) + '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) autoprefixer: 10.4.19(postcss@8.4.38) - babel-loader: 9.1.3(@babel/core@7.23.9)(webpack@5.90.1) + babel-loader: 9.1.3(@babel/core@7.23.9)(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) babel-plugin-dynamic-import-node: 2.3.3 boxen: 6.2.1 chalk: 4.1.2 @@ -20214,34 +20405,34 @@ snapshots: cli-table3: 0.6.3 combine-promises: 1.2.0 commander: 5.1.0 - copy-webpack-plugin: 11.0.0(webpack@5.90.1) + copy-webpack-plugin: 11.0.0(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) core-js: 3.37.1 - css-loader: 6.11.0(webpack@5.90.1) - css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.2)(webpack@5.90.1) + css-loader: 6.11.0(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) + css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.2)(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) cssnano: 6.1.2(postcss@8.4.38) del: 6.1.1 detect-port: 1.5.1 escape-html: 1.0.3 eta: 2.2.0 eval: 0.1.8 - file-loader: 6.2.0(webpack@5.90.1) + file-loader: 6.2.0(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) fs-extra: 11.1.1 html-minifier-terser: 7.2.0 html-tags: 3.3.1 - html-webpack-plugin: 5.5.3(webpack@5.90.1) + html-webpack-plugin: 5.5.3(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) leven: 3.1.0 lodash: 4.17.21 - mini-css-extract-plugin: 2.7.6(webpack@5.90.1) + mini-css-extract-plugin: 2.7.6(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) p-map: 4.0.0 postcss: 8.4.38 - postcss-loader: 7.3.3(postcss@8.4.38)(webpack@5.90.1) + postcss-loader: 7.3.3(postcss@8.4.38)(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) prompts: 2.4.2 react: 18.3.1 - react-dev-utils: 12.0.1(eslint@8.57.0)(typescript@5.4.5)(vue-template-compiler@2.7.16)(webpack@5.90.1) + react-dev-utils: 12.0.1(eslint@8.57.0)(typescript@5.4.5)(vue-template-compiler@2.7.16)(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) react-dom: 18.3.1(react@18.3.1) react-helmet-async: 1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' - react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.90.1) + react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) react-router: 5.3.4(react@18.3.1) react-router-config: 5.1.1(react-router@5.3.4(react@18.3.1))(react@18.3.1) react-router-dom: 5.3.4(react@18.3.1) @@ -20249,15 +20440,15 @@ snapshots: semver: 7.6.0 serve-handler: 6.1.5 shelljs: 0.8.5 - terser-webpack-plugin: 5.3.10(webpack@5.90.1) + terser-webpack-plugin: 5.3.10(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) tslib: 2.6.2 update-notifier: 6.0.2 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.90.1))(webpack@5.90.1) - webpack: 5.90.1 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))))(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) webpack-bundle-analyzer: 4.10.2 - webpack-dev-server: 4.15.2(webpack@5.90.1) + webpack-dev-server: 4.15.2(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) webpack-merge: 5.10.0 - webpackbar: 5.0.2(webpack@5.90.1) + webpackbar: 5.0.2(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) transitivePeerDependencies: - '@docusaurus/types' - '@parcel/css' @@ -20289,16 +20480,16 @@ snapshots: chalk: 4.1.2 tslib: 2.6.2 - '@docusaurus/mdx-loader@3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)': + '@docusaurus/mdx-loader@3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)': dependencies: '@docusaurus/logger': 3.4.0 - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) + '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) + '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) '@mdx-js/mdx': 3.0.1 '@slorber/remark-comment': 1.0.0 escape-html: 1.0.3 estree-util-value-to-estree: 3.1.2 - file-loader: 6.2.0(webpack@5.90.1) + file-loader: 6.2.0(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) fs-extra: 11.1.1 image-size: 1.0.2 mdast-util-mdx: 3.0.0 @@ -20314,9 +20505,9 @@ snapshots: tslib: 2.6.2 unified: 11.0.5 unist-util-visit: 5.0.0 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.90.1))(webpack@5.90.1) + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))))(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) vfile: 6.0.1 - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) transitivePeerDependencies: - '@docusaurus/types' - '@swc/core' @@ -20326,9 +20517,9 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/module-type-aliases@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/module-type-aliases@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/history': 4.7.11 '@types/react': 18.3.3 '@types/react-router-config': 5.0.11 @@ -20344,15 +20535,15 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/plugin-content-blog@3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-content-blog@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) '@docusaurus/logger': 3.4.0 - '@docusaurus/mdx-loader': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5) - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) + '@docusaurus/mdx-loader': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5) + '@docusaurus/types': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) + '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) cheerio: 1.0.0-rc.12 feed: 4.2.2 fs-extra: 11.1.1 @@ -20364,7 +20555,7 @@ snapshots: tslib: 2.6.2 unist-util-visit: 5.0.0 utility-types: 3.11.0 - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) transitivePeerDependencies: - '@parcel/css' - '@rspack/core' @@ -20383,16 +20574,16 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-content-docs@3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-content-docs@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) '@docusaurus/logger': 3.4.0 - '@docusaurus/mdx-loader': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5) - '@docusaurus/module-type-aliases': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) + '@docusaurus/mdx-loader': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5) + '@docusaurus/module-type-aliases': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) + '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) '@types/react-router-config': 5.0.11 combine-promises: 1.2.0 fs-extra: 11.2.0 @@ -20402,7 +20593,7 @@ snapshots: react-dom: 18.3.1(react@18.3.1) tslib: 2.6.2 utility-types: 3.11.0 - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) transitivePeerDependencies: - '@parcel/css' - '@rspack/core' @@ -20421,18 +20612,18 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-content-pages@3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-content-pages@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/mdx-loader': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5) - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) + '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/mdx-loader': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5) + '@docusaurus/types': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) + '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) fs-extra: 11.1.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) tslib: 2.6.2 - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) transitivePeerDependencies: - '@parcel/css' - '@rspack/core' @@ -20451,11 +20642,11 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-debug@3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-debug@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) + '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/types': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) fs-extra: 11.1.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -20479,11 +20670,11 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-google-analytics@3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-google-analytics@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) + '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/types': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) tslib: 2.6.2 @@ -20505,11 +20696,11 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-google-gtag@3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-google-gtag@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) + '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/types': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) '@types/gtag.js': 0.0.12 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -20532,11 +20723,11 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-google-tag-manager@3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-google-tag-manager@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) + '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/types': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) tslib: 2.6.2 @@ -20558,14 +20749,14 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/plugin-sitemap@3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': + '@docusaurus/plugin-sitemap@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) '@docusaurus/logger': 3.4.0 - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) + '@docusaurus/types': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) + '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) fs-extra: 11.1.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -20589,21 +20780,21 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/preset-classic@3.4.0(@algolia/client-search@4.23.3)(@types/react@18.3.3)(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': - dependencies: - '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-content-blog': 3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-content-docs': 3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-content-pages': 3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-debug': 3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-google-analytics': 3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-google-gtag': 3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-google-tag-manager': 3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-sitemap': 3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/theme-classic': 3.4.0(@types/react@18.3.3)(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/theme-common': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/theme-search-algolia': 3.4.0(@algolia/client-search@4.23.3)(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/preset-classic@3.4.0(@algolia/client-search@4.23.3)(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/react@18.3.3)(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': + dependencies: + '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-content-blog': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-content-docs': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-content-pages': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-debug': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-google-analytics': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-google-gtag': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-google-tag-manager': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-sitemap': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/theme-classic': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/react@18.3.3)(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/theme-common': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/theme-search-algolia': 3.4.0(@algolia/client-search@4.23.3)(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/react@18.3.3)(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/types': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) transitivePeerDependencies: @@ -20642,20 +20833,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@docusaurus/theme-classic@3.4.0(@types/react@18.3.3)(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': + '@docusaurus/theme-classic@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/react@18.3.3)(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/mdx-loader': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5) - '@docusaurus/module-type-aliases': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/plugin-content-blog': 3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-content-docs': 3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-content-pages': 3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/theme-common': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/mdx-loader': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5) + '@docusaurus/module-type-aliases': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-blog': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-content-docs': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-content-pages': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/theme-common': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) '@docusaurus/theme-translations': 3.4.0 - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) + '@docusaurus/types': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) + '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) '@mdx-js/react': 3.0.1(@types/react@18.3.3)(react@18.3.1) clsx: 2.1.1 copy-text-to-clipboard: 3.2.0 @@ -20690,15 +20881,15 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/theme-common@3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': + '@docusaurus/theme-common@3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/mdx-loader': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5) - '@docusaurus/module-type-aliases': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/plugin-content-blog': 3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-content-docs': 3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/plugin-content-pages': 3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/mdx-loader': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5) + '@docusaurus/module-type-aliases': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-blog': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-content-docs': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-content-pages': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) + '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) '@types/history': 4.7.11 '@types/react': 18.3.3 '@types/react-router-config': 5.0.11 @@ -20728,13 +20919,13 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/theme-mermaid@3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': + '@docusaurus/theme-mermaid@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': dependencies: - '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/module-type-aliases': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/theme-common': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) + '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/module-type-aliases': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-common': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/types': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) mermaid: 10.9.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -20757,16 +20948,16 @@ snapshots: - vue-template-compiler - webpack-cli - '@docusaurus/theme-search-algolia@3.4.0(@algolia/client-search@4.23.3)(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': + '@docusaurus/theme-search-algolia@3.4.0(@algolia/client-search@4.23.3)(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/react@18.3.3)(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16)': dependencies: '@docsearch/react': 3.6.0(@algolia/client-search@4.23.3)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/core': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) '@docusaurus/logger': 3.4.0 - '@docusaurus/plugin-content-docs': 3.4.0(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) - '@docusaurus/theme-common': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/plugin-content-docs': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) + '@docusaurus/theme-common': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(eslint@8.57.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.4.5)(vue-template-compiler@2.7.16) '@docusaurus/theme-translations': 3.4.0 - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) - '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) + '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) + '@docusaurus/utils-validation': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) algoliasearch: 4.23.3 algoliasearch-helper: 3.22.1(algoliasearch@4.23.3) clsx: 2.1.1 @@ -20806,7 +20997,7 @@ snapshots: '@docusaurus/tsconfig@3.4.0': {} - '@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@mdx-js/mdx': 3.0.1 '@types/history': 4.7.11 @@ -20817,7 +21008,7 @@ snapshots: react-dom: 18.3.1(react@18.3.1) react-helmet-async: 1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) utility-types: 3.11.0 - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) webpack-merge: 5.10.0 transitivePeerDependencies: - '@swc/core' @@ -20826,17 +21017,17 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils-common@3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': + '@docusaurus/utils-common@3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': dependencies: tslib: 2.6.2 optionalDependencies: - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation@3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5)': + '@docusaurus/utils-validation@3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5)': dependencies: '@docusaurus/logger': 3.4.0 - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) + '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) fs-extra: 11.2.0 joi: 17.13.3 js-yaml: 4.1.0 @@ -20851,13 +21042,13 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils@3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5)': + '@docusaurus/utils@3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5)': dependencies: '@docusaurus/logger': 3.4.0 - '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@docusaurus/utils-common': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) '@svgr/webpack': 8.1.0(typescript@5.4.5) escape-string-regexp: 4.0.0 - file-loader: 6.2.0(webpack@5.90.1) + file-loader: 6.2.0(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) fs-extra: 11.2.0 github-slugger: 1.5.0 globby: 11.1.0 @@ -20870,11 +21061,11 @@ snapshots: resolve-pathname: 3.0.0 shelljs: 0.8.5 tslib: 2.6.2 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.90.1))(webpack@5.90.1) + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))))(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) utility-types: 3.11.0 - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) optionalDependencies: - '@docusaurus/types': 3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) transitivePeerDependencies: - '@swc/core' - esbuild @@ -21219,6 +21410,10 @@ snapshots: '@eslint/js@8.57.0': {} + '@ethereumjs/rlp@4.0.1': {} + + '@ethereumjs/rlp@5.0.2': {} + '@faker-js/faker@8.0.2': {} '@fal-works/esbuild-plugin-global-externals@2.1.2': {} @@ -21458,24 +21653,24 @@ snapshots: - encoding - supports-color - '@graphql-markdown/core@1.10.2(@graphql-markdown/printer-legacy@1.8.2(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(graphql@16.8.1)(prettier@3.3.2)(typescript@5.4.5))(graphql-config@5.0.3(@types/node@20.4.2)(graphql@16.8.1))(graphql@16.8.1)(prettier@3.3.2)': + '@graphql-markdown/core@1.10.2(@graphql-markdown/printer-legacy@1.8.2(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(graphql@16.8.1)(prettier@3.3.2)(typescript@5.4.5))(graphql-config@5.0.3(@types/node@20.4.2)(graphql@16.8.1))(graphql@16.8.1)(prettier@3.3.2)': dependencies: '@graphql-markdown/graphql': 1.1.3(graphql@16.8.1)(prettier@3.3.2) '@graphql-markdown/logger': 1.0.3 '@graphql-markdown/utils': 1.6.5(prettier@3.3.2) optionalDependencies: - '@graphql-markdown/printer-legacy': 1.8.2(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(graphql@16.8.1)(prettier@3.3.2)(typescript@5.4.5) + '@graphql-markdown/printer-legacy': 1.8.2(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(graphql@16.8.1)(prettier@3.3.2)(typescript@5.4.5) graphql-config: 5.0.3(@types/node@20.4.2)(graphql@16.8.1) transitivePeerDependencies: - graphql - prettier - '@graphql-markdown/docusaurus@1.24.2(@docusaurus/logger@3.4.0)(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(graphql-config@5.0.3(@types/node@20.4.2)(graphql@16.8.1))(graphql@16.8.1)(prettier@3.3.2)(typescript@5.4.5)': + '@graphql-markdown/docusaurus@1.24.2(@docusaurus/logger@3.4.0)(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(graphql-config@5.0.3(@types/node@20.4.2)(graphql@16.8.1))(graphql@16.8.1)(prettier@3.3.2)(typescript@5.4.5)': dependencies: '@docusaurus/logger': 3.4.0 - '@graphql-markdown/core': 1.10.2(@graphql-markdown/printer-legacy@1.8.2(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(graphql@16.8.1)(prettier@3.3.2)(typescript@5.4.5))(graphql-config@5.0.3(@types/node@20.4.2)(graphql@16.8.1))(graphql@16.8.1)(prettier@3.3.2) + '@graphql-markdown/core': 1.10.2(@graphql-markdown/printer-legacy@1.8.2(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(graphql@16.8.1)(prettier@3.3.2)(typescript@5.4.5))(graphql-config@5.0.3(@types/node@20.4.2)(graphql@16.8.1))(graphql@16.8.1)(prettier@3.3.2) '@graphql-markdown/logger': 1.0.3 - '@graphql-markdown/printer-legacy': 1.8.2(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(graphql@16.8.1)(prettier@3.3.2)(typescript@5.4.5) + '@graphql-markdown/printer-legacy': 1.8.2(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(graphql@16.8.1)(prettier@3.3.2)(typescript@5.4.5) transitivePeerDependencies: - '@docusaurus/types' - '@graphql-markdown/diff' @@ -21500,9 +21695,9 @@ snapshots: '@graphql-markdown/logger@1.0.3': {} - '@graphql-markdown/printer-legacy@1.8.2(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(graphql@16.8.1)(prettier@3.3.2)(typescript@5.4.5)': + '@graphql-markdown/printer-legacy@1.8.2(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(graphql@16.8.1)(prettier@3.3.2)(typescript@5.4.5)': dependencies: - '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.4.5) + '@docusaurus/utils': 3.4.0(@docusaurus/types@3.4.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@swc/core@1.3.92(@swc/helpers@0.5.5))(typescript@5.4.5) '@graphql-markdown/graphql': 1.1.3(graphql@16.8.1)(prettier@3.3.2) '@graphql-markdown/utils': 1.6.5(prettier@3.3.2) transitivePeerDependencies: @@ -21835,9 +22030,9 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@headlessui/tailwindcss@0.1.3(tailwindcss@3.3.3(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.3.3)))': + '@headlessui/tailwindcss@0.1.3(tailwindcss@3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)))': dependencies: - tailwindcss: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + tailwindcss: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) '@hookform/resolvers@3.1.1(react-hook-form@7.45.2(react@18.3.1))': dependencies: @@ -21895,7 +22090,7 @@ snapshots: jest-util: 29.7.0 slash: 3.0.0 - '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3))': + '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0(node-notifier@10.0.0) @@ -21909,7 +22104,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + jest-config: 29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -21932,7 +22127,7 @@ snapshots: - supports-color - ts-node - '@jest/core@29.7.0(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5))': + '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0(node-notifier@10.0.0) @@ -21946,7 +22141,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.4.2)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)) + jest-config: 29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -21962,6 +22157,8 @@ snapshots: pretty-format: 29.7.0 slash: 3.0.0 strip-ansi: 6.0.1 + optionalDependencies: + node-notifier: 10.0.0 transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -22362,6 +22559,31 @@ snapshots: '@metamask/browser-passworder@4.1.0': {} + '@metamask/object-multiplex@1.3.0': + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + readable-stream: 2.3.8 + + '@metamask/providers@10.2.1': + dependencies: + '@metamask/object-multiplex': 1.3.0 + '@metamask/safe-event-emitter': 2.0.0 + '@types/chrome': 0.0.136 + detect-browser: 5.3.0 + eth-rpc-errors: 4.0.3 + extension-port-stream: 2.1.1 + fast-deep-equal: 2.0.1 + is-stream: 2.0.1 + json-rpc-engine: 6.1.0 + json-rpc-middleware-stream: 4.2.3 + pump: 3.0.0 + webextension-polyfill-ts: 0.25.0 + + '@metamask/safe-event-emitter@2.0.0': {} + + '@metamask/safe-event-emitter@3.1.1': {} + '@microsoft/api-extractor-model@7.28.13(@types/node@20.4.2)': dependencies: '@microsoft/tsdoc': 0.14.2 @@ -22515,7 +22737,7 @@ snapshots: cache-manager: 5.6.1 rxjs: 7.8.1 - '@nestjs/cli@10.3.2(@swc/core@1.3.92)': + '@nestjs/cli@10.3.2(@swc/core@1.3.92(@swc/helpers@0.5.5))': dependencies: '@angular-devkit/core': 17.1.2(chokidar@3.6.0) '@angular-devkit/schematics': 17.1.2(chokidar@3.6.0) @@ -22525,7 +22747,7 @@ snapshots: chokidar: 3.6.0 cli-table3: 0.6.3 commander: 4.1.1 - fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.3.3)(webpack@5.90.1(@swc/core@1.3.92)) + fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.3.3)(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) glob: 10.3.10 inquirer: 8.2.6 node-emoji: 1.11.0 @@ -22537,7 +22759,7 @@ snapshots: tsconfig-paths: 4.2.0 tsconfig-paths-webpack-plugin: 4.1.0 typescript: 5.3.3 - webpack: 5.90.1(@swc/core@1.3.92) + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) webpack-node-externals: 3.0.0 optionalDependencies: '@swc/core': 1.3.92(@swc/helpers@0.5.5) @@ -22656,8 +22878,14 @@ snapshots: dependencies: '@noble/hashes': 1.3.1 + '@noble/curves@1.4.2': + dependencies: + '@noble/hashes': 1.4.0 + '@noble/hashes@1.3.1': {} + '@noble/hashes@1.4.0': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -23998,17 +24226,30 @@ snapshots: '@scure/base@1.1.1': {} + '@scure/base@1.1.7': {} + '@scure/bip32@1.3.1': dependencies: '@noble/curves': 1.1.0 '@noble/hashes': 1.3.1 '@scure/base': 1.1.1 + '@scure/bip32@1.4.0': + dependencies: + '@noble/curves': 1.4.2 + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.7 + '@scure/bip39@1.2.1': dependencies: '@noble/hashes': 1.3.1 '@scure/base': 1.1.1 + '@scure/bip39@1.3.0': + dependencies: + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.7 + '@sentry-internal/tracing@7.59.2': dependencies: '@sentry/core': 7.59.2 @@ -25047,14 +25288,14 @@ snapshots: - encoding - supports-color - '@storybook/test@8.1.11(@jest/globals@29.7.0)(@types/jest@29.5.3)(jest@29.7.0(@types/node@20.4.2)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)))(vitest@0.33.0(sass@1.63.6)(terser@5.31.0))': + '@storybook/test@8.1.11(@jest/globals@29.7.0)(@types/jest@29.5.3)(jest@29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)))(vitest@0.33.0(@vitest/ui@0.33.0)(happy-dom@10.5.1)(jsdom@23.0.0)(sass@1.63.6)(terser@5.31.0))': dependencies: '@storybook/client-logger': 8.1.11 '@storybook/core-events': 8.1.11 '@storybook/instrumenter': 8.1.11 '@storybook/preview-api': 8.1.11 '@testing-library/dom': 10.1.0 - '@testing-library/jest-dom': 6.4.5(@jest/globals@29.7.0)(@types/jest@29.5.3)(jest@29.7.0(@types/node@20.4.2)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)))(vitest@0.33.0(sass@1.63.6)(terser@5.31.0)) + '@testing-library/jest-dom': 6.4.5(@jest/globals@29.7.0)(@types/jest@29.5.3)(jest@29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)))(vitest@0.33.0(@vitest/ui@0.33.0)(happy-dom@10.5.1)(jsdom@23.0.0)(sass@1.63.6)(terser@5.31.0)) '@testing-library/user-event': 14.5.2(@testing-library/dom@10.1.0) '@vitest/expect': 1.6.0 '@vitest/spy': 1.6.0 @@ -25368,14 +25609,14 @@ snapshots: dependencies: defer-to-connect: 2.0.1 - '@tailwindcss/aspect-ratio@0.4.2(tailwindcss@3.3.3(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.3.3)))': + '@tailwindcss/aspect-ratio@0.4.2(tailwindcss@3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)))': dependencies: - tailwindcss: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + tailwindcss: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) - '@tailwindcss/forms@0.5.4(tailwindcss@3.3.3(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.3.3)))': + '@tailwindcss/forms@0.5.4(tailwindcss@3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)))': dependencies: mini-svg-data-uri: 1.4.4 - tailwindcss: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + tailwindcss: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) '@tanstack/eslint-plugin-query@5.43.1(eslint@8.57.0)(typescript@5.4.5)': dependencies: @@ -25465,7 +25706,7 @@ snapshots: lodash: 4.17.21 redent: 3.0.0 - '@testing-library/jest-dom@6.4.5(@jest/globals@29.7.0)(@types/jest@29.5.3)(jest@29.7.0(@types/node@20.4.2)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)))(vitest@0.33.0(sass@1.63.6)(terser@5.31.0))': + '@testing-library/jest-dom@6.4.5(@jest/globals@29.7.0)(@types/jest@29.5.3)(jest@29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)))(vitest@0.33.0(@vitest/ui@0.33.0)(happy-dom@10.5.1)(jsdom@23.0.0)(sass@1.63.6)(terser@5.31.0))': dependencies: '@adobe/css-tools': 4.4.0 '@babel/runtime': 7.23.9 @@ -25478,7 +25719,7 @@ snapshots: optionalDependencies: '@jest/globals': 29.7.0 '@types/jest': 29.5.3 - jest: 29.7.0(@types/node@20.4.2)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)) + jest: 29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)) vitest: 0.33.0(@vitest/ui@0.33.0)(happy-dom@10.5.1)(jsdom@23.0.0)(sass@1.63.6)(terser@5.31.0) '@testing-library/react@14.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': @@ -25551,6 +25792,11 @@ snapshots: '@types/chai@4.3.5': {} + '@types/chrome@0.0.136': + dependencies: + '@types/filesystem': 0.0.36 + '@types/har-format': 1.2.15 + '@types/connect-history-api-fallback@1.5.4': dependencies: '@types/express-serve-static-core': 4.17.35 @@ -25656,6 +25902,12 @@ snapshots: '@types/qs': 6.9.7 '@types/serve-static': 1.15.2 + '@types/filesystem@0.0.36': + dependencies: + '@types/filewriter': 0.0.33 + + '@types/filewriter@0.0.33': {} + '@types/find-cache-dir@3.2.1': {} '@types/geojson@7946.0.10': {} @@ -25673,6 +25925,8 @@ snapshots: '@types/gtag.js@0.0.12': {} + '@types/har-format@1.2.15': {} + '@types/hast@2.3.10': dependencies: '@types/unist': 2.0.7 @@ -25924,17 +26178,21 @@ snapshots: '@types/webextension-polyfill@0.10.1': {} - '@types/webpack@5.28.1(@swc/core@1.3.92)(webpack-cli@5.0.1(webpack@5.79.0))': + '@types/webpack@5.28.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))': dependencies: '@types/node': 20.4.2 tapable: 2.2.1 - webpack: 5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1) + webpack: 5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0)) transitivePeerDependencies: - '@swc/core' - esbuild - uglify-js - webpack-cli + '@types/ws@8.5.3': + dependencies: + '@types/node': 20.4.2 + '@types/ws@8.5.9': dependencies: '@types/node': 20.4.2 @@ -26386,12 +26644,12 @@ snapshots: dependencies: '@vanilla-extract/css': 1.13.0 - '@vanilla-extract/vite-plugin@3.9.0(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.3.3))(vite@4.4.11(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0))': + '@vanilla-extract/vite-plugin@3.9.0(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3))(vite@4.4.11(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0))': dependencies: '@vanilla-extract/integration': 6.2.2(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0) outdent: 0.8.0 postcss: 8.4.38 - postcss-load-config: 3.1.4(postcss@8.4.38)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.3.3)) + postcss-load-config: 3.1.4(postcss@8.4.38)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) vite: 4.4.11(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0) transitivePeerDependencies: - '@types/node' @@ -26404,12 +26662,12 @@ snapshots: - terser - ts-node - '@vanilla-extract/vite-plugin@3.9.0(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.3.3))(vite@4.4.4(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0))': + '@vanilla-extract/vite-plugin@3.9.0(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3))(vite@4.4.4(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0))': dependencies: '@vanilla-extract/integration': 6.2.2(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0) outdent: 0.8.0 postcss: 8.4.38 - postcss-load-config: 3.1.4(postcss@8.4.38)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.3.3)) + postcss-load-config: 3.1.4(postcss@8.4.38)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) vite: 4.4.4(@types/node@20.4.2)(sass@1.63.6)(terser@5.31.0) transitivePeerDependencies: - '@types/node' @@ -26875,19 +27133,19 @@ snapshots: '@webassemblyjs/ast': 1.12.1 '@xtuc/long': 4.2.2 - '@webpack-cli/configtest@2.0.1(webpack-cli@5.0.1(webpack@5.79.0))(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1))': + '@webpack-cli/configtest@2.0.1(webpack-cli@5.0.1(webpack@5.79.0))(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0)))': dependencies: - webpack: 5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1) + webpack: 5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0)) webpack-cli: 5.0.1(webpack@5.79.0) - '@webpack-cli/info@2.0.1(webpack-cli@5.0.1(webpack@5.79.0))(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1))': + '@webpack-cli/info@2.0.1(webpack-cli@5.0.1(webpack@5.79.0))(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0)))': dependencies: - webpack: 5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1) + webpack: 5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0)) webpack-cli: 5.0.1(webpack@5.79.0) - '@webpack-cli/serve@2.0.1(webpack-cli@5.0.1(webpack@5.79.0))(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1))': + '@webpack-cli/serve@2.0.1(webpack-cli@5.0.1(webpack@5.79.0))(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0)))': dependencies: - webpack: 5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1) + webpack: 5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0)) webpack-cli: 5.0.1(webpack@5.79.0) '@whatwg-node/events@0.0.3': {} @@ -26947,6 +27205,12 @@ snapshots: '@zxing/text-encoding@0.9.0': optional: true + abitype@0.7.1(typescript@5.4.5)(zod@3.21.4): + dependencies: + typescript: 5.4.5 + optionalDependencies: + zod: 3.21.4 + abort-controller@3.0.0: dependencies: event-target-shim: 5.0.1 @@ -26982,12 +27246,12 @@ snapshots: acorn@8.8.2: {} - addons-linter@5.32.0(body-parser@1.20.2)(express@4.18.2)(node-fetch@3.3.1): + addons-linter@5.32.0(body-parser@1.20.2)(express@4.19.2)(node-fetch@3.3.1): dependencies: '@fluent/syntax': 0.19.0 '@mdn/browser-compat-data': 5.2.42 addons-moz-compare: 1.3.0 - addons-scanner-utils: 8.5.0(body-parser@1.20.2)(express@4.18.2)(node-fetch@3.3.1) + addons-scanner-utils: 8.5.0(body-parser@1.20.2)(express@4.19.2)(node-fetch@3.3.1) ajv: 8.12.0 chalk: 4.1.2 cheerio: 1.0.0-rc.12 @@ -27025,7 +27289,7 @@ snapshots: addons-moz-compare@1.3.0: {} - addons-scanner-utils@8.5.0(body-parser@1.20.2)(express@4.18.2)(node-fetch@3.3.1): + addons-scanner-utils@8.5.0(body-parser@1.20.2)(express@4.19.2)(node-fetch@3.3.1): dependencies: '@types/yauzl': 2.10.0 common-tags: 1.8.2 @@ -27035,7 +27299,7 @@ snapshots: yauzl: 2.10.0 optionalDependencies: body-parser: 1.20.2 - express: 4.18.2 + express: 4.19.2 node-fetch: 3.3.1 address@1.2.2: {} @@ -27430,12 +27694,12 @@ snapshots: transitivePeerDependencies: - supports-color - babel-loader@9.1.3(@babel/core@7.23.9)(webpack@5.90.1): + babel-loader@9.1.3(@babel/core@7.23.9)(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))): dependencies: '@babel/core': 7.23.9 find-cache-dir: 4.0.0 schema-utils: 4.2.0 - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) babel-plugin-dynamic-import-node@2.3.3: dependencies: @@ -28395,7 +28659,7 @@ snapshots: copy-text-to-clipboard@3.2.0: {} - copy-webpack-plugin@11.0.0(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)): + copy-webpack-plugin@11.0.0(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))): dependencies: fast-glob: 3.2.12 glob-parent: 6.0.2 @@ -28403,9 +28667,9 @@ snapshots: normalize-path: 3.0.0 schema-utils: 4.0.0 serialize-javascript: 6.0.1 - webpack: 5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1) + webpack: 5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0)) - copy-webpack-plugin@11.0.0(webpack@5.90.1): + copy-webpack-plugin@11.0.0(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))): dependencies: fast-glob: 3.2.12 glob-parent: 6.0.2 @@ -28413,7 +28677,7 @@ snapshots: normalize-path: 3.0.0 schema-utils: 4.0.0 serialize-javascript: 6.0.1 - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) core-js-compat@3.31.1: dependencies: @@ -28490,13 +28754,15 @@ snapshots: optionalDependencies: typescript: 5.4.5 - create-jest@29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)): + crc-32@1.2.2: {} + + create-jest@29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + jest-config: 29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -28505,13 +28771,13 @@ snapshots: - supports-color - ts-node - create-jest@29.7.0(@types/node@20.4.2)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)): + create-jest@29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.4.2)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)) + jest-config: 29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -28544,6 +28810,12 @@ snapshots: transitivePeerDependencies: - encoding + cross-fetch@4.0.0: + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + cross-inspect@1.0.0: dependencies: tslib: 2.6.2 @@ -28590,7 +28862,7 @@ snapshots: postcss-selector-parser: 6.1.0 postcss-value-parser: 4.2.0 - css-loader@6.11.0(webpack@5.90.1): + css-loader@6.11.0(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))): dependencies: icss-utils: 5.1.0(postcss@8.4.38) postcss: 8.4.38 @@ -28601,9 +28873,9 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.6.0 optionalDependencies: - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) - css-loader@6.7.3(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)): + css-loader@6.7.3(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))): dependencies: icss-utils: 5.1.0(postcss@8.4.38) postcss: 8.4.38 @@ -28613,9 +28885,9 @@ snapshots: postcss-modules-values: 4.0.0(postcss@8.4.38) postcss-value-parser: 4.2.0 semver: 7.5.4 - webpack: 5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1) + webpack: 5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0)) - css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.2)(webpack@5.90.1): + css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.2)(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))): dependencies: '@jridgewell/trace-mapping': 0.3.22 cssnano: 6.1.2(postcss@8.4.38) @@ -28623,7 +28895,7 @@ snapshots: postcss: 8.4.38 schema-utils: 4.2.0 serialize-javascript: 6.0.1 - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) optionalDependencies: clean-css: 5.3.2 @@ -29129,6 +29401,8 @@ snapshots: destroy@1.2.0: {} + detect-browser@5.3.0: {} + detect-indent@6.1.0: {} detect-libc@1.0.3: {} @@ -30040,7 +30314,7 @@ snapshots: eslint-visitor-keys@3.4.3: {} - eslint-webpack-plugin@4.0.1(eslint@8.57.0)(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)): + eslint-webpack-plugin@4.0.1(eslint@8.57.0)(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))): dependencies: '@types/eslint': 8.37.0 eslint: 8.57.0 @@ -30048,7 +30322,7 @@ snapshots: micromatch: 4.0.5 normalize-path: 3.0.0 schema-utils: 4.0.0 - webpack: 5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1) + webpack: 5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0)) eslint@8.36.0: dependencies: @@ -30254,6 +30528,17 @@ snapshots: etag@1.8.1: {} + eth-rpc-errors@4.0.3: + dependencies: + fast-safe-stringify: 2.1.1 + + ethereum-cryptography@2.2.1: + dependencies: + '@noble/curves': 1.4.2 + '@noble/hashes': 1.4.0 + '@scure/bip32': 1.4.0 + '@scure/bip39': 1.3.0 + eval@0.1.8: dependencies: '@types/node': 20.4.2 @@ -30412,6 +30697,10 @@ snapshots: extendable-error@0.1.7: {} + extension-port-stream@2.1.1: + dependencies: + webextension-polyfill: 0.10.0 + external-editor@3.1.0: dependencies: chardet: 0.7.0 @@ -30437,6 +30726,8 @@ snapshots: fast-decode-uri-component@1.0.1: {} + fast-deep-equal@2.0.1: {} + fast-deep-equal@3.1.3: {} fast-diff@1.3.0: {} @@ -30551,11 +30842,11 @@ snapshots: dependencies: flat-cache: 3.0.4 - file-loader@6.2.0(webpack@5.90.1): + file-loader@6.2.0(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) file-system-cache@2.3.0: dependencies: @@ -30674,7 +30965,7 @@ snapshots: forever-agent@0.6.1: {} - fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.0)(typescript@5.4.5)(vue-template-compiler@2.7.16)(webpack@5.90.1): + fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.0)(typescript@5.4.5)(vue-template-compiler@2.7.16)(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))): dependencies: '@babel/code-frame': 7.23.5 '@types/json-schema': 7.0.14 @@ -30690,12 +30981,12 @@ snapshots: semver: 7.6.0 tapable: 1.1.3 typescript: 5.4.5 - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) optionalDependencies: eslint: 8.57.0 vue-template-compiler: 2.7.16 - fork-ts-checker-webpack-plugin@9.0.2(typescript@5.3.3)(webpack@5.90.1(@swc/core@1.3.92)): + fork-ts-checker-webpack-plugin@9.0.2(typescript@5.3.3)(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))): dependencies: '@babel/code-frame': 7.23.5 chalk: 4.1.2 @@ -30710,7 +31001,7 @@ snapshots: semver: 7.6.0 tapable: 2.2.1 typescript: 5.3.3 - webpack: 5.90.1(@swc/core@1.3.92) + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) form-data-encoder@2.1.4: {} @@ -31501,23 +31792,23 @@ snapshots: html-void-elements@3.0.0: {} - html-webpack-plugin@5.5.3(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)): + html-webpack-plugin@5.5.3(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 lodash: 4.17.21 pretty-error: 4.0.0 tapable: 2.2.1 - webpack: 5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1) + webpack: 5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0)) - html-webpack-plugin@5.5.3(webpack@5.90.1): + html-webpack-plugin@5.5.3(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 lodash: 4.17.21 pretty-error: 4.0.0 tapable: 2.2.1 - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) htmlparser2@6.1.0: dependencies: @@ -32204,16 +32495,16 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)): + jest-cli@29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + create-jest: 29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + jest-config: 29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -32225,19 +32516,21 @@ snapshots: - supports-color - ts-node - jest-cli@29.7.0(@types/node@20.4.2)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)): + jest-cli@29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.4.2)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)) + create-jest: 29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.4.2)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)) + jest-config: 29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 + optionalDependencies: + node-notifier: 10.0.0 transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -32245,7 +32538,7 @@ snapshots: - ts-node optional: true - jest-config@29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)): + jest-config@29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)): dependencies: '@babel/core': 7.23.9 '@jest/test-sequencer': 29.7.0 @@ -32271,12 +32564,12 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 20.4.2 - ts-node: 10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3) + ts-node: 10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3) transitivePeerDependencies: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@20.4.2)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)): + jest-config@29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)): dependencies: '@babel/core': 7.23.9 '@jest/test-sequencer': 29.7.0 @@ -32302,7 +32595,7 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 20.4.2 - ts-node: 10.9.1(@types/node@20.4.2)(typescript@5.4.5) + ts-node: 10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -32597,12 +32890,12 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)): + jest@29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + jest-cli: 29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) optionalDependencies: node-notifier: 10.0.0 transitivePeerDependencies: @@ -32611,12 +32904,14 @@ snapshots: - supports-color - ts-node - jest@29.7.0(@types/node@20.4.2)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)): + jest@29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)) '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.4.2)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)) + jest-cli: 29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)) + optionalDependencies: + node-notifier: 10.0.0 transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -32759,6 +33054,17 @@ snapshots: json-parse-even-better-errors@2.3.1: {} + json-rpc-engine@6.1.0: + dependencies: + '@metamask/safe-event-emitter': 2.0.0 + eth-rpc-errors: 4.0.3 + + json-rpc-middleware-stream@4.2.3: + dependencies: + '@metamask/safe-event-emitter': 3.1.1 + json-rpc-engine: 6.1.0 + readable-stream: 2.3.8 + json-schema-traverse@0.4.1: {} json-schema-traverse@1.0.0: {} @@ -33927,15 +34233,15 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.7.6(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)): + mini-css-extract-plugin@2.7.6(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))): dependencies: schema-utils: 4.2.0 - webpack: 5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1) + webpack: 5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0)) - mini-css-extract-plugin@2.7.6(webpack@5.90.1): + mini-css-extract-plugin@2.7.6(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))): dependencies: schema-utils: 4.2.0 - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) mini-svg-data-uri@1.4.4: {} @@ -34122,7 +34428,7 @@ snapshots: neo-async@2.6.2: {} - next@14.2.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.63.6): + next@14.2.3(@playwright/test@1.36.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.63.6): dependencies: '@next/env': 14.2.3 '@swc/helpers': 0.5.5 @@ -34143,6 +34449,7 @@ snapshots: '@next/swc-win32-arm64-msvc': 14.2.3 '@next/swc-win32-ia32-msvc': 14.2.3 '@next/swc-win32-x64-msvc': 14.2.3 + '@playwright/test': 1.36.1 sass: 1.63.6 transitivePeerDependencies: - '@babel/core' @@ -34913,45 +35220,45 @@ snapshots: '@csstools/postcss-progressive-custom-properties': 3.0.0(postcss@8.4.31) postcss: 8.4.31 - postcss-load-config@3.1.4(postcss@8.4.38)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.3.3)): + postcss-load-config@3.1.4(postcss@8.4.38)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)): dependencies: lilconfig: 2.1.0 yaml: 2.3.1 optionalDependencies: postcss: 8.4.38 - ts-node: 10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3) + ts-node: 10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3) - postcss-load-config@4.0.1(postcss@8.4.38)(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)): + postcss-load-config@4.0.1(postcss@8.4.38)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)): dependencies: lilconfig: 2.1.0 yaml: 2.3.1 optionalDependencies: postcss: 8.4.38 - ts-node: 10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3) + ts-node: 10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3) - postcss-load-config@4.0.1(postcss@8.4.38)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)): + postcss-load-config@4.0.1(postcss@8.4.38)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)): dependencies: lilconfig: 2.1.0 - yaml: 2.3.1 + yaml: 2.4.2 optionalDependencies: postcss: 8.4.38 - ts-node: 10.9.1(@types/node@20.4.2)(typescript@5.4.5) + ts-node: 10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5) - postcss-loader@7.3.3(postcss@8.4.31)(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)): + postcss-loader@7.3.3(postcss@8.4.31)(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))): dependencies: cosmiconfig: 8.2.0 jiti: 1.19.1 postcss: 8.4.31 semver: 7.5.4 - webpack: 5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1) + webpack: 5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0)) - postcss-loader@7.3.3(postcss@8.4.38)(webpack@5.90.1): + postcss-loader@7.3.3(postcss@8.4.38)(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))): dependencies: cosmiconfig: 8.2.0 jiti: 1.19.1 postcss: 8.4.38 semver: 7.5.4 - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) postcss-logical@7.0.0(postcss@8.4.31): dependencies: @@ -35496,7 +35803,7 @@ snapshots: react: 18.3.1 tween-functions: 1.2.0 - react-dev-utils@12.0.1(eslint@8.57.0)(typescript@5.4.5)(vue-template-compiler@2.7.16)(webpack@5.90.1): + react-dev-utils@12.0.1(eslint@8.57.0)(typescript@5.4.5)(vue-template-compiler@2.7.16)(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))): dependencies: '@babel/code-frame': 7.23.5 address: 1.2.2 @@ -35507,7 +35814,7 @@ snapshots: escape-string-regexp: 4.0.0 filesize: 8.0.7 find-up: 5.0.0 - fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.0)(typescript@5.4.5)(vue-template-compiler@2.7.16)(webpack@5.90.1) + fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.0)(typescript@5.4.5)(vue-template-compiler@2.7.16)(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) global-modules: 2.0.0 globby: 11.1.0 gzip-size: 6.0.0 @@ -35522,7 +35829,7 @@ snapshots: shell-quote: 1.8.1 strip-ansi: 6.0.1 text-table: 0.2.0 - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) optionalDependencies: typescript: 5.4.5 transitivePeerDependencies: @@ -35623,11 +35930,11 @@ snapshots: dependencies: react: 18.3.1 - react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.90.1): + react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))): dependencies: '@babel/runtime': 7.23.9 react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) react-number-format@5.2.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: @@ -36303,10 +36610,10 @@ snapshots: safer-buffer@2.1.2: {} - sass-loader@13.3.2(sass@1.63.6)(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)): + sass-loader@13.3.2(sass@1.63.6)(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))): dependencies: neo-async: 2.6.2 - webpack: 5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1) + webpack: 5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0)) optionalDependencies: sass: 1.63.6 @@ -37117,11 +37424,11 @@ snapshots: tailwind-merge@1.14.0: {} - tailwindcss-animate@1.0.6(tailwindcss@3.3.3(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.3.3))): + tailwindcss-animate@1.0.6(tailwindcss@3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3))): dependencies: - tailwindcss: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + tailwindcss: 3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) - tailwindcss@3.3.3(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)): + tailwindcss@3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -37140,7 +37447,7 @@ snapshots: postcss: 8.4.38 postcss-import: 15.1.0(postcss@8.4.38) postcss-js: 4.0.1(postcss@8.4.38) - postcss-load-config: 4.0.1(postcss@8.4.38)(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + postcss-load-config: 4.0.1(postcss@8.4.38)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) postcss-nested: 6.0.1(postcss@8.4.38) postcss-selector-parser: 6.0.13 resolve: 1.22.2 @@ -37148,7 +37455,7 @@ snapshots: transitivePeerDependencies: - ts-node - tailwindcss@3.3.3(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)): + tailwindcss@3.3.3(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -37167,7 +37474,7 @@ snapshots: postcss: 8.4.38 postcss-import: 15.1.0(postcss@8.4.38) postcss-js: 4.0.1(postcss@8.4.38) - postcss-load-config: 4.0.1(postcss@8.4.38)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)) + postcss-load-config: 4.0.1(postcss@8.4.38)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)) postcss-nested: 6.0.1(postcss@8.4.38) postcss-selector-parser: 6.0.13 resolve: 1.22.2 @@ -37175,7 +37482,7 @@ snapshots: transitivePeerDependencies: - ts-node - tailwindcss@3.4.4(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)): + tailwindcss@3.4.4(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -37194,7 +37501,7 @@ snapshots: postcss: 8.4.38 postcss-import: 15.1.0(postcss@8.4.38) postcss-js: 4.0.1(postcss@8.4.38) - postcss-load-config: 4.0.1(postcss@8.4.38)(ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5)) + postcss-load-config: 4.0.1(postcss@8.4.38)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5)) postcss-nested: 6.0.1(postcss@8.4.38) postcss-selector-parser: 6.1.0 resolve: 1.22.8 @@ -37254,34 +37561,25 @@ snapshots: term-size@2.2.1: {} - terser-webpack-plugin@5.3.10(@swc/core@1.3.92)(webpack@5.90.1(@swc/core@1.3.92)): + terser-webpack-plugin@5.3.10(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))): dependencies: '@jridgewell/trace-mapping': 0.3.22 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.1 terser: 5.31.0 - webpack: 5.90.1(@swc/core@1.3.92) + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) optionalDependencies: '@swc/core': 1.3.92(@swc/helpers@0.5.5) - terser-webpack-plugin@5.3.10(webpack@5.90.1): - dependencies: - '@jridgewell/trace-mapping': 0.3.22 - jest-worker: 27.5.1 - schema-utils: 3.3.0 - serialize-javascript: 6.0.1 - terser: 5.31.0 - webpack: 5.90.1 - - terser-webpack-plugin@5.3.7(@swc/core@1.3.92)(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)): + terser-webpack-plugin@5.3.7(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))): dependencies: '@jridgewell/trace-mapping': 0.3.18 jest-worker: 27.5.1 schema-utils: 3.1.1 serialize-javascript: 6.0.1 terser: 5.16.9 - webpack: 5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1) + webpack: 5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0)) optionalDependencies: '@swc/core': 1.3.92(@swc/helpers@0.5.5) @@ -37437,11 +37735,11 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-jest@29.1.3(@babel/core@7.23.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(jest@29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)))(typescript@5.3.3): + ts-jest@29.1.3(@babel/core@7.23.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(jest@29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)))(typescript@5.3.3): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3)) + jest: 29.7.0(@types/node@20.4.2)(babel-plugin-macros@3.1.0)(node-notifier@10.0.0)(ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3)) jest-util: 29.6.1 json5: 2.2.3 lodash.memoize: 4.1.2 @@ -37455,27 +37753,27 @@ snapshots: '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.23.9) - ts-loader@9.4.4(typescript@5.3.3)(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)): + ts-loader@9.4.4(typescript@5.3.3)(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))): dependencies: chalk: 4.1.2 enhanced-resolve: 5.15.0 micromatch: 4.0.7 semver: 7.6.0 typescript: 5.3.3 - webpack: 5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1) + webpack: 5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0)) - ts-loader@9.4.4(typescript@5.3.3)(webpack@5.90.1(@swc/core@1.3.92)): + ts-loader@9.4.4(typescript@5.3.3)(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))): dependencies: chalk: 4.1.2 enhanced-resolve: 5.15.0 micromatch: 4.0.7 semver: 7.6.0 typescript: 5.3.3 - webpack: 5.90.1(@swc/core@1.3.92) + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) ts-log@2.2.5: {} - ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.4.2)(typescript@5.3.3): + ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.3.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.9 @@ -37495,7 +37793,7 @@ snapshots: optionalDependencies: '@swc/core': 1.3.92(@swc/helpers@0.5.5) - ts-node@10.9.1(@types/node@20.4.2)(typescript@5.4.5): + ts-node@10.9.1(@swc/core@1.3.92(@swc/helpers@0.5.5))(@types/node@20.4.2)(typescript@5.4.5): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.9 @@ -37512,6 +37810,8 @@ snapshots: typescript: 5.4.5 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + optionalDependencies: + '@swc/core': 1.3.92(@swc/helpers@0.5.5) optional: true ts-retry-promise@0.7.0: {} @@ -37881,14 +38181,14 @@ snapshots: dependencies: punycode: 2.3.1 - url-loader@4.1.1(file-loader@6.2.0(webpack@5.90.1))(webpack@5.90.1): + url-loader@4.1.1(file-loader@6.2.0(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))))(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))): dependencies: loader-utils: 2.0.4 mime-types: 2.1.35 schema-utils: 3.3.0 - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) optionalDependencies: - file-loader: 6.2.0(webpack@5.90.1) + file-loader: 6.2.0(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) url-parse@1.5.10: dependencies: @@ -38233,11 +38533,11 @@ snapshots: optionalDependencies: '@zxing/text-encoding': 0.9.0 - web-ext@7.6.2(body-parser@1.20.2)(express@4.18.2): + web-ext@7.6.2(body-parser@1.20.2)(express@4.19.2): dependencies: '@babel/runtime': 7.21.0 '@devicefarmer/adbkit': 3.2.3 - addons-linter: 5.32.0(body-parser@1.20.2)(express@4.18.2)(node-fetch@3.3.1) + addons-linter: 5.32.0(body-parser@1.20.2)(express@4.19.2)(node-fetch@3.3.1) bunyan: 1.8.15 camelcase: 7.0.1 chrome-launcher: 0.15.1 @@ -38283,6 +38583,231 @@ snapshots: web-worker@1.3.0: {} + web3-core@4.5.0: + dependencies: + web3-errors: 1.2.0 + web3-eth-accounts: 4.1.3 + web3-eth-iban: 4.0.7 + web3-providers-http: 4.1.0 + web3-providers-ws: 4.0.8 + web3-types: 1.7.0 + web3-utils: 4.3.1 + web3-validator: 2.0.6 + optionalDependencies: + web3-providers-ipc: 4.0.7 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + web3-errors@1.2.0: + dependencies: + web3-types: 1.7.0 + + web3-eth-abi@4.2.3(typescript@5.4.5)(zod@3.21.4): + dependencies: + abitype: 0.7.1(typescript@5.4.5)(zod@3.21.4) + web3-errors: 1.2.0 + web3-types: 1.7.0 + web3-utils: 4.3.1 + web3-validator: 2.0.6 + transitivePeerDependencies: + - typescript + - zod + + web3-eth-accounts@4.1.3: + dependencies: + '@ethereumjs/rlp': 4.0.1 + crc-32: 1.2.2 + ethereum-cryptography: 2.2.1 + web3-errors: 1.2.0 + web3-types: 1.7.0 + web3-utils: 4.3.1 + web3-validator: 2.0.6 + + web3-eth-contract@4.6.0(typescript@5.4.5)(zod@3.21.4): + dependencies: + '@ethereumjs/rlp': 5.0.2 + web3-core: 4.5.0 + web3-errors: 1.2.0 + web3-eth: 4.8.1(typescript@5.4.5)(zod@3.21.4) + web3-eth-abi: 4.2.3(typescript@5.4.5)(zod@3.21.4) + web3-types: 1.7.0 + web3-utils: 4.3.1 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + web3-eth-ens@4.4.0(typescript@5.4.5)(zod@3.21.4): + dependencies: + '@adraffy/ens-normalize': 1.10.1 + web3-core: 4.5.0 + web3-errors: 1.2.0 + web3-eth: 4.8.1(typescript@5.4.5)(zod@3.21.4) + web3-eth-contract: 4.6.0(typescript@5.4.5)(zod@3.21.4) + web3-net: 4.1.0 + web3-types: 1.7.0 + web3-utils: 4.3.1 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + web3-eth-iban@4.0.7: + dependencies: + web3-errors: 1.2.0 + web3-types: 1.7.0 + web3-utils: 4.3.1 + web3-validator: 2.0.6 + + web3-eth-personal@4.0.8(typescript@5.4.5)(zod@3.21.4): + dependencies: + web3-core: 4.5.0 + web3-eth: 4.8.1(typescript@5.4.5)(zod@3.21.4) + web3-rpc-methods: 1.3.0 + web3-types: 1.7.0 + web3-utils: 4.3.1 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + web3-eth@4.8.1(typescript@5.4.5)(zod@3.21.4): + dependencies: + setimmediate: 1.0.5 + web3-core: 4.5.0 + web3-errors: 1.2.0 + web3-eth-abi: 4.2.3(typescript@5.4.5)(zod@3.21.4) + web3-eth-accounts: 4.1.3 + web3-net: 4.1.0 + web3-providers-ws: 4.0.8 + web3-rpc-methods: 1.3.0 + web3-types: 1.7.0 + web3-utils: 4.3.1 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + web3-net@4.1.0: + dependencies: + web3-core: 4.5.0 + web3-rpc-methods: 1.3.0 + web3-types: 1.7.0 + web3-utils: 4.3.1 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + web3-providers-http@4.1.0: + dependencies: + cross-fetch: 4.0.0 + web3-errors: 1.2.0 + web3-types: 1.7.0 + web3-utils: 4.3.1 + transitivePeerDependencies: + - encoding + + web3-providers-ipc@4.0.7: + dependencies: + web3-errors: 1.2.0 + web3-types: 1.7.0 + web3-utils: 4.3.1 + optional: true + + web3-providers-ws@4.0.8: + dependencies: + '@types/ws': 8.5.3 + isomorphic-ws: 5.0.0(ws@8.17.1) + web3-errors: 1.2.0 + web3-types: 1.7.0 + web3-utils: 4.3.1 + ws: 8.17.1 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + web3-rpc-methods@1.3.0: + dependencies: + web3-core: 4.5.0 + web3-types: 1.7.0 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + web3-rpc-providers@1.0.0-rc.1: + dependencies: + web3-errors: 1.2.0 + web3-providers-http: 4.1.0 + web3-providers-ws: 4.0.8 + web3-types: 1.7.0 + web3-utils: 4.3.1 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + web3-types@1.7.0: {} + + web3-utils@4.3.1: + dependencies: + ethereum-cryptography: 2.2.1 + eventemitter3: 5.0.1 + web3-errors: 1.2.0 + web3-types: 1.7.0 + web3-validator: 2.0.6 + + web3-validator@2.0.6: + dependencies: + ethereum-cryptography: 2.2.1 + util: 0.12.5 + web3-errors: 1.2.0 + web3-types: 1.7.0 + zod: 3.21.4 + + web3@4.11.0(typescript@5.4.5)(zod@3.21.4): + dependencies: + web3-core: 4.5.0 + web3-errors: 1.2.0 + web3-eth: 4.8.1(typescript@5.4.5)(zod@3.21.4) + web3-eth-abi: 4.2.3(typescript@5.4.5)(zod@3.21.4) + web3-eth-accounts: 4.1.3 + web3-eth-contract: 4.6.0(typescript@5.4.5)(zod@3.21.4) + web3-eth-ens: 4.4.0(typescript@5.4.5)(zod@3.21.4) + web3-eth-iban: 4.0.7 + web3-eth-personal: 4.0.8(typescript@5.4.5)(zod@3.21.4) + web3-net: 4.1.0 + web3-providers-http: 4.1.0 + web3-providers-ws: 4.0.8 + web3-rpc-methods: 1.3.0 + web3-rpc-providers: 1.0.0-rc.1 + web3-types: 1.7.0 + web3-utils: 4.3.1 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + webcrypto-core@1.7.8: dependencies: '@peculiar/asn1-schema': 2.3.8 @@ -38291,8 +38816,14 @@ snapshots: pvtsutils: 1.3.5 tslib: 2.6.2 + webextension-polyfill-ts@0.25.0: + dependencies: + webextension-polyfill: 0.7.0 + webextension-polyfill@0.10.0: {} + webextension-polyfill@0.7.0: {} + webidl-conversions@3.0.1: {} webidl-conversions@7.0.0: {} @@ -38318,9 +38849,9 @@ snapshots: webpack-cli@5.0.1(webpack@5.79.0): dependencies: '@discoveryjs/json-ext': 0.5.7 - '@webpack-cli/configtest': 2.0.1(webpack-cli@5.0.1(webpack@5.79.0))(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)) - '@webpack-cli/info': 2.0.1(webpack-cli@5.0.1(webpack@5.79.0))(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)) - '@webpack-cli/serve': 2.0.1(webpack-cli@5.0.1(webpack@5.79.0))(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)) + '@webpack-cli/configtest': 2.0.1(webpack-cli@5.0.1(webpack@5.79.0))(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))) + '@webpack-cli/info': 2.0.1(webpack-cli@5.0.1(webpack@5.79.0))(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))) + '@webpack-cli/serve': 2.0.1(webpack-cli@5.0.1(webpack@5.79.0))(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))) colorette: 2.0.19 commander: 9.5.0 cross-spawn: 7.0.3 @@ -38329,19 +38860,19 @@ snapshots: import-local: 3.1.0 interpret: 3.1.1 rechoir: 0.8.0 - webpack: 5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1) + webpack: 5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0)) webpack-merge: 5.8.0 - webpack-dev-middleware@5.3.4(webpack@5.90.1): + webpack-dev-middleware@5.3.4(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))): dependencies: colorette: 2.0.20 memfs: 3.5.3 mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.2.0 - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) - webpack-dev-server@4.15.2(webpack@5.90.1): + webpack-dev-server@4.15.2(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -38371,10 +38902,10 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 5.3.4(webpack@5.90.1) + webpack-dev-middleware: 5.3.4(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) ws: 8.17.1 optionalDependencies: - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) transitivePeerDependencies: - bufferutil - debug @@ -38398,7 +38929,7 @@ snapshots: webpack-virtual-modules@0.5.0: {} - webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1): + webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0)): dependencies: '@types/eslint-scope': 3.7.4 '@types/estree': 1.0.0 @@ -38421,7 +38952,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.1.1 tapable: 2.2.1 - terser-webpack-plugin: 5.3.7(@swc/core@1.3.92)(webpack@5.79.0(@swc/core@1.3.92)(webpack-cli@5.0.1)) + terser-webpack-plugin: 5.3.7(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack@5.79.0(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack-cli@5.0.1(webpack@5.79.0))) watchpack: 2.4.0 webpack-sources: 3.2.3 optionalDependencies: @@ -38431,38 +38962,7 @@ snapshots: - esbuild - uglify-js - webpack@5.90.1: - dependencies: - '@types/eslint-scope': 3.7.4 - '@types/estree': 1.0.5 - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/wasm-edit': 1.12.1 - '@webassemblyjs/wasm-parser': 1.12.1 - acorn: 8.10.0 - acorn-import-assertions: 1.9.0(acorn@8.10.0) - browserslist: 4.22.3 - chrome-trace-event: 1.0.3 - enhanced-resolve: 5.15.0 - es-module-lexer: 1.2.1 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.0 - mime-types: 2.1.35 - neo-async: 2.6.2 - schema-utils: 3.3.0 - tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(webpack@5.90.1) - watchpack: 2.4.0 - webpack-sources: 3.2.3 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js - - webpack@5.90.1(@swc/core@1.3.92): + webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)): dependencies: '@types/eslint-scope': 3.7.4 '@types/estree': 1.0.5 @@ -38485,7 +38985,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(@swc/core@1.3.92)(webpack@5.90.1(@swc/core@1.3.92)) + terser-webpack-plugin: 5.3.10(@swc/core@1.3.92(@swc/helpers@0.5.5))(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))) watchpack: 2.4.0 webpack-sources: 3.2.3 transitivePeerDependencies: @@ -38493,13 +38993,13 @@ snapshots: - esbuild - uglify-js - webpackbar@5.0.2(webpack@5.90.1): + webpackbar@5.0.2(webpack@5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5))): dependencies: chalk: 4.1.2 consola: 2.15.3 pretty-time: 1.1.0 std-env: 3.3.3 - webpack: 5.90.1 + webpack: 5.90.1(@swc/core@1.3.92(@swc/helpers@0.5.5)) websocket-driver@0.7.4: dependencies: From 5f3ed29ba651149d7a59b9f0f977307b44605d1f Mon Sep 17 00:00:00 2001 From: Jeroen van den Hout Date: Mon, 10 Jun 2024 22:06:08 +0200 Subject: [PATCH 11/37] refactor(docs): rename to IOTA Chains --- .../_EVM-required-prior-knowledge.md | 0 .../_admonitions/_EVM_compatibility.md | 0 .../_admonitions/_about-accounts.md | 0 .../_admonitions/_deploy_a_smart_contract.md | 0 .../_admonitions/_ownership.md | 0 .../_admonitions/_payable.md | 0 .../_admonitions/_remix-IDE.md | 0 .../_partials/_hardhat_config.mdx | 0 .../_partials/_on_off_ledger_request.md | 0 .../how-tos/token/_check_storage_deposit.md | 0 .../how-tos/token/_example_code_intro.mdx | 0 .../how-tos/token/_obsolete_token_creation.md | 0 .../explanations/consensus.md | 0 .../explanations/context.mdx | 0 .../explanations/core-contracts.md | 0 .../explanations/how-accounts-work.md | 0 .../explanations/invocation.md | 0 .../explanations/sandbox.md | 0 .../explanations/smart-contract-anatomy.md | 0 .../explanations/smart-contracts.md | 0 .../explanations/state_manager.md | 0 .../explanations/states.md | 0 .../explanations/validators.md | 0 .../getting-started/compatibility.md | 0 .../getting-started/languages-and-vms.md | 0 .../getting-started/networks-and-chains.mdx | 0 .../getting-started/quick-start.mdx | 0 .../getting-started/tools.mdx | 0 .../how-tos/ERC20.md | 0 .../how-tos/ERC721.md | 0 .../core-contracts/basics/allowance/allow.md | 0 .../basics/allowance/get-allowance.md | 0 .../basics/allowance/take-allowance.md | 0 .../core-contracts/basics/get-balance.md | 0 .../basics/send-assets-to-l1.mdx | 0 .../how-tos/core-contracts/call-view.md | 0 .../core-contracts/get-randomness-on-l2.md | 0 .../how-tos/core-contracts/introduction.md | 0 .../core-contracts/nft/introduction.md | 0 .../how-tos/core-contracts/nft/mint-nft.md | 0 .../core-contracts/nft/use-as-erc721.md | 0 .../core-contracts/token/create-foundry.md | 0 .../token/create-native-token.md | 0 .../token/erc20-native-token.md | 0 .../core-contracts/token/introduction.md | 0 .../core-contracts/token/mint-token.md | 0 .../core-contracts/token/register-token.md | 0 .../how-tos/create-a-basic-contract.md | 0 .../how-tos/deploy-a-smart-contract.mdx | 0 .../how-tos/introduction.md | 0 .../how-tos/send-ERC20-across-chains.md | 0 .../how-tos/send-NFTs-across-chains.md | 0 .../how-tos/send-funds-from-L1-to-L2.mdx | 0 .../how-tos/test-smart-contracts.md | 0 .../introduction.md | 0 .../schema/how-tos/access.mdx | 0 .../schema/how-tos/call.mdx | 0 .../schema/how-tos/events.mdx | 0 .../schema/how-tos/funcdesc.mdx | 0 .../schema/how-tos/funcs.mdx | 0 .../schema/how-tos/init.mdx | 0 .../schema/how-tos/params.mdx | 0 .../schema/how-tos/post.mdx | 0 .../schema/how-tos/results.mdx | 0 .../schema/how-tos/spec.mdx | 0 .../schema/how-tos/state.mdx | 0 .../schema/how-tos/structs.mdx | 0 .../schema/how-tos/thunks.mdx | 0 .../schema/how-tos/transfers.mdx | 0 .../schema/how-tos/typedefs.mdx | 0 .../schema/how-tos/usage.mdx | 0 .../schema/how-tos/views.mdx | 0 .../schema/how-tos/yaml.mdx | 0 .../schema/introduction.mdx | 0 .../schema/proxies.mdx | 0 .../solo/getting-started.md | 0 .../solo/how-tos/deploying-sc.md | 0 .../solo/how-tos/error-handling.md | 0 .../solo/how-tos/examples.mdx | 0 .../solo/how-tos/first-example.md | 0 .../solo/how-tos/invoking-sc.md | 0 .../solo/how-tos/test.mdx | 0 .../solo/how-tos/the-l1-ledger.md | 0 .../solo/how-tos/the-l2-ledger.md | 0 .../solo/how-tos/timelock.mdx | 0 .../solo/how-tos/view-sc.md | 0 .../how-tos/chain-management.md | 0 .../how-tos/running-a-node.md | 0 .../how-tos/running-an-access-node.md | 0 .../how-tos/setting-up-a-chain.md | 0 .../how-tos/wasp-cli.md | 0 .../reference/configuration.md | 0 .../reference/metrics.md | 0 .../.gitignore | 0 .../core-contracts/accounts.md | 0 .../core-contracts/blob.md | 0 .../core-contracts/blocklog.md | 0 .../core-contracts/errors.md | 0 .../core-contracts/evm.md | 0 .../core-contracts/governance.md | 0 .../core-contracts/overview.md | 0 .../core-contracts/root.md | 0 .../core-contracts/xfer.md | 0 .../json-rpc-spec.md | 0 .../magic-contract/introduction.md | 0 .../wasm-lib-data-types.mdx | 0 docs/content/sidebars/developer.js | 142 +++++++++--------- docs/content/sidebars/operator.js | 18 +-- docs/content/sidebars/references.js | 26 ++-- docs/site/package.json | 4 +- ...ences.sh => get-iota-chains-references.sh} | 4 +- 111 files changed, 97 insertions(+), 97 deletions(-) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/_admonitions/_EVM-required-prior-knowledge.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/_admonitions/_EVM_compatibility.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/_admonitions/_about-accounts.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/_admonitions/_deploy_a_smart_contract.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/_admonitions/_ownership.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/_admonitions/_payable.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/_admonitions/_remix-IDE.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/_partials/_hardhat_config.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/_partials/_on_off_ledger_request.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/_partials/how-tos/token/_check_storage_deposit.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/_partials/how-tos/token/_example_code_intro.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/_partials/how-tos/token/_obsolete_token_creation.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/explanations/consensus.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/explanations/context.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/explanations/core-contracts.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/explanations/how-accounts-work.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/explanations/invocation.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/explanations/sandbox.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/explanations/smart-contract-anatomy.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/explanations/smart-contracts.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/explanations/state_manager.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/explanations/states.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/explanations/validators.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/getting-started/compatibility.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/getting-started/languages-and-vms.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/getting-started/networks-and-chains.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/getting-started/quick-start.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/getting-started/tools.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/ERC20.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/ERC721.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/core-contracts/basics/allowance/allow.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/core-contracts/basics/allowance/get-allowance.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/core-contracts/basics/allowance/take-allowance.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/core-contracts/basics/get-balance.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/core-contracts/basics/send-assets-to-l1.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/core-contracts/call-view.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/core-contracts/get-randomness-on-l2.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/core-contracts/introduction.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/core-contracts/nft/introduction.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/core-contracts/nft/mint-nft.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/core-contracts/nft/use-as-erc721.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/core-contracts/token/create-foundry.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/core-contracts/token/create-native-token.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/core-contracts/token/erc20-native-token.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/core-contracts/token/introduction.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/core-contracts/token/mint-token.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/core-contracts/token/register-token.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/create-a-basic-contract.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/deploy-a-smart-contract.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/introduction.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/send-ERC20-across-chains.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/send-NFTs-across-chains.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/send-funds-from-L1-to-L2.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/how-tos/test-smart-contracts.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/introduction.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/schema/how-tos/access.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/schema/how-tos/call.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/schema/how-tos/events.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/schema/how-tos/funcdesc.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/schema/how-tos/funcs.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/schema/how-tos/init.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/schema/how-tos/params.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/schema/how-tos/post.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/schema/how-tos/results.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/schema/how-tos/spec.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/schema/how-tos/state.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/schema/how-tos/structs.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/schema/how-tos/thunks.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/schema/how-tos/transfers.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/schema/how-tos/typedefs.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/schema/how-tos/usage.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/schema/how-tos/views.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/schema/how-tos/yaml.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/schema/introduction.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/schema/proxies.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/solo/getting-started.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/solo/how-tos/deploying-sc.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/solo/how-tos/error-handling.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/solo/how-tos/examples.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/solo/how-tos/first-example.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/solo/how-tos/invoking-sc.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/solo/how-tos/test.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/solo/how-tos/the-l1-ledger.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/solo/how-tos/the-l2-ledger.md (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/solo/how-tos/timelock.mdx (100%) rename docs/content/guides/developer/{layer-2-smart-contracts => iota-chains}/solo/how-tos/view-sc.md (100%) rename docs/content/guides/operator/{layer-2-smart-contracts-node => iota-chains-node}/how-tos/chain-management.md (100%) rename docs/content/guides/operator/{layer-2-smart-contracts-node => iota-chains-node}/how-tos/running-a-node.md (100%) rename docs/content/guides/operator/{layer-2-smart-contracts-node => iota-chains-node}/how-tos/running-an-access-node.md (100%) rename docs/content/guides/operator/{layer-2-smart-contracts-node => iota-chains-node}/how-tos/setting-up-a-chain.md (100%) rename docs/content/guides/operator/{layer-2-smart-contracts-node => iota-chains-node}/how-tos/wasp-cli.md (100%) rename docs/content/guides/operator/{layer-2-smart-contracts-node => iota-chains-node}/reference/configuration.md (100%) rename docs/content/guides/operator/{layer-2-smart-contracts-node => iota-chains-node}/reference/metrics.md (100%) rename docs/content/references/{layer-2-smart-contracts => iota-chains}/.gitignore (100%) rename docs/content/references/{layer-2-smart-contracts => iota-chains}/core-contracts/accounts.md (100%) rename docs/content/references/{layer-2-smart-contracts => iota-chains}/core-contracts/blob.md (100%) rename docs/content/references/{layer-2-smart-contracts => iota-chains}/core-contracts/blocklog.md (100%) rename docs/content/references/{layer-2-smart-contracts => iota-chains}/core-contracts/errors.md (100%) rename docs/content/references/{layer-2-smart-contracts => iota-chains}/core-contracts/evm.md (100%) rename docs/content/references/{layer-2-smart-contracts => iota-chains}/core-contracts/governance.md (100%) rename docs/content/references/{layer-2-smart-contracts => iota-chains}/core-contracts/overview.md (100%) rename docs/content/references/{layer-2-smart-contracts => iota-chains}/core-contracts/root.md (100%) rename docs/content/references/{layer-2-smart-contracts => iota-chains}/core-contracts/xfer.md (100%) rename docs/content/references/{layer-2-smart-contracts => iota-chains}/json-rpc-spec.md (100%) rename docs/content/references/{layer-2-smart-contracts => iota-chains}/magic-contract/introduction.md (100%) rename docs/content/references/{layer-2-smart-contracts => iota-chains}/wasm-lib-data-types.mdx (100%) rename docs/site/scripts/{get_wasp_references.sh => get-iota-chains-references.sh} (69%) diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_EVM-required-prior-knowledge.md b/docs/content/guides/developer/iota-chains/_admonitions/_EVM-required-prior-knowledge.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_EVM-required-prior-knowledge.md rename to docs/content/guides/developer/iota-chains/_admonitions/_EVM-required-prior-knowledge.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_EVM_compatibility.md b/docs/content/guides/developer/iota-chains/_admonitions/_EVM_compatibility.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_EVM_compatibility.md rename to docs/content/guides/developer/iota-chains/_admonitions/_EVM_compatibility.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_about-accounts.md b/docs/content/guides/developer/iota-chains/_admonitions/_about-accounts.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_about-accounts.md rename to docs/content/guides/developer/iota-chains/_admonitions/_about-accounts.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_deploy_a_smart_contract.md b/docs/content/guides/developer/iota-chains/_admonitions/_deploy_a_smart_contract.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_deploy_a_smart_contract.md rename to docs/content/guides/developer/iota-chains/_admonitions/_deploy_a_smart_contract.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_ownership.md b/docs/content/guides/developer/iota-chains/_admonitions/_ownership.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_ownership.md rename to docs/content/guides/developer/iota-chains/_admonitions/_ownership.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_payable.md b/docs/content/guides/developer/iota-chains/_admonitions/_payable.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_payable.md rename to docs/content/guides/developer/iota-chains/_admonitions/_payable.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_remix-IDE.md b/docs/content/guides/developer/iota-chains/_admonitions/_remix-IDE.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/_admonitions/_remix-IDE.md rename to docs/content/guides/developer/iota-chains/_admonitions/_remix-IDE.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_partials/_hardhat_config.mdx b/docs/content/guides/developer/iota-chains/_partials/_hardhat_config.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/_partials/_hardhat_config.mdx rename to docs/content/guides/developer/iota-chains/_partials/_hardhat_config.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_partials/_on_off_ledger_request.md b/docs/content/guides/developer/iota-chains/_partials/_on_off_ledger_request.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/_partials/_on_off_ledger_request.md rename to docs/content/guides/developer/iota-chains/_partials/_on_off_ledger_request.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_partials/how-tos/token/_check_storage_deposit.md b/docs/content/guides/developer/iota-chains/_partials/how-tos/token/_check_storage_deposit.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/_partials/how-tos/token/_check_storage_deposit.md rename to docs/content/guides/developer/iota-chains/_partials/how-tos/token/_check_storage_deposit.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_partials/how-tos/token/_example_code_intro.mdx b/docs/content/guides/developer/iota-chains/_partials/how-tos/token/_example_code_intro.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/_partials/how-tos/token/_example_code_intro.mdx rename to docs/content/guides/developer/iota-chains/_partials/how-tos/token/_example_code_intro.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/_partials/how-tos/token/_obsolete_token_creation.md b/docs/content/guides/developer/iota-chains/_partials/how-tos/token/_obsolete_token_creation.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/_partials/how-tos/token/_obsolete_token_creation.md rename to docs/content/guides/developer/iota-chains/_partials/how-tos/token/_obsolete_token_creation.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/consensus.md b/docs/content/guides/developer/iota-chains/explanations/consensus.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/explanations/consensus.md rename to docs/content/guides/developer/iota-chains/explanations/consensus.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/context.mdx b/docs/content/guides/developer/iota-chains/explanations/context.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/explanations/context.mdx rename to docs/content/guides/developer/iota-chains/explanations/context.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/core-contracts.md b/docs/content/guides/developer/iota-chains/explanations/core-contracts.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/explanations/core-contracts.md rename to docs/content/guides/developer/iota-chains/explanations/core-contracts.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/how-accounts-work.md b/docs/content/guides/developer/iota-chains/explanations/how-accounts-work.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/explanations/how-accounts-work.md rename to docs/content/guides/developer/iota-chains/explanations/how-accounts-work.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/invocation.md b/docs/content/guides/developer/iota-chains/explanations/invocation.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/explanations/invocation.md rename to docs/content/guides/developer/iota-chains/explanations/invocation.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/sandbox.md b/docs/content/guides/developer/iota-chains/explanations/sandbox.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/explanations/sandbox.md rename to docs/content/guides/developer/iota-chains/explanations/sandbox.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/smart-contract-anatomy.md b/docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/explanations/smart-contract-anatomy.md rename to docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/smart-contracts.md b/docs/content/guides/developer/iota-chains/explanations/smart-contracts.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/explanations/smart-contracts.md rename to docs/content/guides/developer/iota-chains/explanations/smart-contracts.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/state_manager.md b/docs/content/guides/developer/iota-chains/explanations/state_manager.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/explanations/state_manager.md rename to docs/content/guides/developer/iota-chains/explanations/state_manager.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/states.md b/docs/content/guides/developer/iota-chains/explanations/states.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/explanations/states.md rename to docs/content/guides/developer/iota-chains/explanations/states.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/explanations/validators.md b/docs/content/guides/developer/iota-chains/explanations/validators.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/explanations/validators.md rename to docs/content/guides/developer/iota-chains/explanations/validators.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/getting-started/compatibility.md b/docs/content/guides/developer/iota-chains/getting-started/compatibility.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/getting-started/compatibility.md rename to docs/content/guides/developer/iota-chains/getting-started/compatibility.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/getting-started/languages-and-vms.md b/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/getting-started/languages-and-vms.md rename to docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/getting-started/networks-and-chains.mdx b/docs/content/guides/developer/iota-chains/getting-started/networks-and-chains.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/getting-started/networks-and-chains.mdx rename to docs/content/guides/developer/iota-chains/getting-started/networks-and-chains.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/getting-started/quick-start.mdx b/docs/content/guides/developer/iota-chains/getting-started/quick-start.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/getting-started/quick-start.mdx rename to docs/content/guides/developer/iota-chains/getting-started/quick-start.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/getting-started/tools.mdx b/docs/content/guides/developer/iota-chains/getting-started/tools.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/getting-started/tools.mdx rename to docs/content/guides/developer/iota-chains/getting-started/tools.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/ERC20.md b/docs/content/guides/developer/iota-chains/how-tos/ERC20.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/ERC20.md rename to docs/content/guides/developer/iota-chains/how-tos/ERC20.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/ERC721.md b/docs/content/guides/developer/iota-chains/how-tos/ERC721.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/ERC721.md rename to docs/content/guides/developer/iota-chains/how-tos/ERC721.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/allow.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/allowance/allow.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/allow.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/allowance/allow.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/get-allowance.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/allowance/get-allowance.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/get-allowance.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/allowance/get-allowance.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/take-allowance.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/allowance/take-allowance.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/take-allowance.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/allowance/take-allowance.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/get-balance.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/get-balance.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/get-balance.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/get-balance.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/send-assets-to-l1.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/send-assets-to-l1.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/send-assets-to-l1.mdx rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/send-assets-to-l1.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/call-view.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/call-view.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/call-view.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/call-view.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/get-randomness-on-l2.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/get-randomness-on-l2.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/get-randomness-on-l2.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/get-randomness-on-l2.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/introduction.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/introduction.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/introduction.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/introduction.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/introduction.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/introduction.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/introduction.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/introduction.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/mint-nft.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/mint-nft.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/use-as-erc721.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/use-as-erc721.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/use-as-erc721.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/use-as-erc721.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/create-foundry.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/create-foundry.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/create-native-token.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/create-native-token.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/erc20-native-token.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/erc20-native-token.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/erc20-native-token.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/erc20-native-token.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/introduction.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/introduction.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/introduction.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/introduction.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/mint-token.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/mint-token.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/register-token.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/register-token.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/register-token.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/register-token.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/create-a-basic-contract.md b/docs/content/guides/developer/iota-chains/how-tos/create-a-basic-contract.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/create-a-basic-contract.md rename to docs/content/guides/developer/iota-chains/how-tos/create-a-basic-contract.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/deploy-a-smart-contract.mdx b/docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/deploy-a-smart-contract.mdx rename to docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/introduction.md b/docs/content/guides/developer/iota-chains/how-tos/introduction.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/introduction.md rename to docs/content/guides/developer/iota-chains/how-tos/introduction.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/send-ERC20-across-chains.md b/docs/content/guides/developer/iota-chains/how-tos/send-ERC20-across-chains.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/send-ERC20-across-chains.md rename to docs/content/guides/developer/iota-chains/how-tos/send-ERC20-across-chains.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/send-NFTs-across-chains.md b/docs/content/guides/developer/iota-chains/how-tos/send-NFTs-across-chains.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/send-NFTs-across-chains.md rename to docs/content/guides/developer/iota-chains/how-tos/send-NFTs-across-chains.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/send-funds-from-L1-to-L2.mdx b/docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/send-funds-from-L1-to-L2.mdx rename to docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/how-tos/test-smart-contracts.md b/docs/content/guides/developer/iota-chains/how-tos/test-smart-contracts.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/how-tos/test-smart-contracts.md rename to docs/content/guides/developer/iota-chains/how-tos/test-smart-contracts.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/introduction.md b/docs/content/guides/developer/iota-chains/introduction.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/introduction.md rename to docs/content/guides/developer/iota-chains/introduction.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/access.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/access.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/access.mdx rename to docs/content/guides/developer/iota-chains/schema/how-tos/access.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/call.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/call.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/call.mdx rename to docs/content/guides/developer/iota-chains/schema/how-tos/call.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/events.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/events.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/events.mdx rename to docs/content/guides/developer/iota-chains/schema/how-tos/events.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/funcdesc.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/funcdesc.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/funcdesc.mdx rename to docs/content/guides/developer/iota-chains/schema/how-tos/funcdesc.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/funcs.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/funcs.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/funcs.mdx rename to docs/content/guides/developer/iota-chains/schema/how-tos/funcs.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/init.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/init.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/init.mdx rename to docs/content/guides/developer/iota-chains/schema/how-tos/init.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/params.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/params.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/params.mdx rename to docs/content/guides/developer/iota-chains/schema/how-tos/params.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/post.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/post.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/post.mdx rename to docs/content/guides/developer/iota-chains/schema/how-tos/post.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/results.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/results.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/results.mdx rename to docs/content/guides/developer/iota-chains/schema/how-tos/results.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/spec.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/spec.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/spec.mdx rename to docs/content/guides/developer/iota-chains/schema/how-tos/spec.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/state.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/state.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/state.mdx rename to docs/content/guides/developer/iota-chains/schema/how-tos/state.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/structs.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/structs.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/structs.mdx rename to docs/content/guides/developer/iota-chains/schema/how-tos/structs.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/thunks.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/thunks.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/thunks.mdx rename to docs/content/guides/developer/iota-chains/schema/how-tos/thunks.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/transfers.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/transfers.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/transfers.mdx rename to docs/content/guides/developer/iota-chains/schema/how-tos/transfers.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/typedefs.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/typedefs.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/typedefs.mdx rename to docs/content/guides/developer/iota-chains/schema/how-tos/typedefs.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/usage.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/usage.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/usage.mdx rename to docs/content/guides/developer/iota-chains/schema/how-tos/usage.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/views.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/views.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/views.mdx rename to docs/content/guides/developer/iota-chains/schema/how-tos/views.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/yaml.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/yaml.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/schema/how-tos/yaml.mdx rename to docs/content/guides/developer/iota-chains/schema/how-tos/yaml.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/introduction.mdx b/docs/content/guides/developer/iota-chains/schema/introduction.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/schema/introduction.mdx rename to docs/content/guides/developer/iota-chains/schema/introduction.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/schema/proxies.mdx b/docs/content/guides/developer/iota-chains/schema/proxies.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/schema/proxies.mdx rename to docs/content/guides/developer/iota-chains/schema/proxies.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/getting-started.md b/docs/content/guides/developer/iota-chains/solo/getting-started.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/solo/getting-started.md rename to docs/content/guides/developer/iota-chains/solo/getting-started.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/deploying-sc.md b/docs/content/guides/developer/iota-chains/solo/how-tos/deploying-sc.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/deploying-sc.md rename to docs/content/guides/developer/iota-chains/solo/how-tos/deploying-sc.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/error-handling.md b/docs/content/guides/developer/iota-chains/solo/how-tos/error-handling.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/error-handling.md rename to docs/content/guides/developer/iota-chains/solo/how-tos/error-handling.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/examples.mdx b/docs/content/guides/developer/iota-chains/solo/how-tos/examples.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/examples.mdx rename to docs/content/guides/developer/iota-chains/solo/how-tos/examples.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/first-example.md b/docs/content/guides/developer/iota-chains/solo/how-tos/first-example.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/first-example.md rename to docs/content/guides/developer/iota-chains/solo/how-tos/first-example.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/invoking-sc.md b/docs/content/guides/developer/iota-chains/solo/how-tos/invoking-sc.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/invoking-sc.md rename to docs/content/guides/developer/iota-chains/solo/how-tos/invoking-sc.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/test.mdx b/docs/content/guides/developer/iota-chains/solo/how-tos/test.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/test.mdx rename to docs/content/guides/developer/iota-chains/solo/how-tos/test.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/the-l1-ledger.md b/docs/content/guides/developer/iota-chains/solo/how-tos/the-l1-ledger.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/the-l1-ledger.md rename to docs/content/guides/developer/iota-chains/solo/how-tos/the-l1-ledger.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/the-l2-ledger.md b/docs/content/guides/developer/iota-chains/solo/how-tos/the-l2-ledger.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/the-l2-ledger.md rename to docs/content/guides/developer/iota-chains/solo/how-tos/the-l2-ledger.md diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/timelock.mdx b/docs/content/guides/developer/iota-chains/solo/how-tos/timelock.mdx similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/timelock.mdx rename to docs/content/guides/developer/iota-chains/solo/how-tos/timelock.mdx diff --git a/docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/view-sc.md b/docs/content/guides/developer/iota-chains/solo/how-tos/view-sc.md similarity index 100% rename from docs/content/guides/developer/layer-2-smart-contracts/solo/how-tos/view-sc.md rename to docs/content/guides/developer/iota-chains/solo/how-tos/view-sc.md diff --git a/docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/chain-management.md b/docs/content/guides/operator/iota-chains-node/how-tos/chain-management.md similarity index 100% rename from docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/chain-management.md rename to docs/content/guides/operator/iota-chains-node/how-tos/chain-management.md diff --git a/docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/running-a-node.md b/docs/content/guides/operator/iota-chains-node/how-tos/running-a-node.md similarity index 100% rename from docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/running-a-node.md rename to docs/content/guides/operator/iota-chains-node/how-tos/running-a-node.md diff --git a/docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/running-an-access-node.md b/docs/content/guides/operator/iota-chains-node/how-tos/running-an-access-node.md similarity index 100% rename from docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/running-an-access-node.md rename to docs/content/guides/operator/iota-chains-node/how-tos/running-an-access-node.md diff --git a/docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/setting-up-a-chain.md b/docs/content/guides/operator/iota-chains-node/how-tos/setting-up-a-chain.md similarity index 100% rename from docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/setting-up-a-chain.md rename to docs/content/guides/operator/iota-chains-node/how-tos/setting-up-a-chain.md diff --git a/docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/wasp-cli.md b/docs/content/guides/operator/iota-chains-node/how-tos/wasp-cli.md similarity index 100% rename from docs/content/guides/operator/layer-2-smart-contracts-node/how-tos/wasp-cli.md rename to docs/content/guides/operator/iota-chains-node/how-tos/wasp-cli.md diff --git a/docs/content/guides/operator/layer-2-smart-contracts-node/reference/configuration.md b/docs/content/guides/operator/iota-chains-node/reference/configuration.md similarity index 100% rename from docs/content/guides/operator/layer-2-smart-contracts-node/reference/configuration.md rename to docs/content/guides/operator/iota-chains-node/reference/configuration.md diff --git a/docs/content/guides/operator/layer-2-smart-contracts-node/reference/metrics.md b/docs/content/guides/operator/iota-chains-node/reference/metrics.md similarity index 100% rename from docs/content/guides/operator/layer-2-smart-contracts-node/reference/metrics.md rename to docs/content/guides/operator/iota-chains-node/reference/metrics.md diff --git a/docs/content/references/layer-2-smart-contracts/.gitignore b/docs/content/references/iota-chains/.gitignore similarity index 100% rename from docs/content/references/layer-2-smart-contracts/.gitignore rename to docs/content/references/iota-chains/.gitignore diff --git a/docs/content/references/layer-2-smart-contracts/core-contracts/accounts.md b/docs/content/references/iota-chains/core-contracts/accounts.md similarity index 100% rename from docs/content/references/layer-2-smart-contracts/core-contracts/accounts.md rename to docs/content/references/iota-chains/core-contracts/accounts.md diff --git a/docs/content/references/layer-2-smart-contracts/core-contracts/blob.md b/docs/content/references/iota-chains/core-contracts/blob.md similarity index 100% rename from docs/content/references/layer-2-smart-contracts/core-contracts/blob.md rename to docs/content/references/iota-chains/core-contracts/blob.md diff --git a/docs/content/references/layer-2-smart-contracts/core-contracts/blocklog.md b/docs/content/references/iota-chains/core-contracts/blocklog.md similarity index 100% rename from docs/content/references/layer-2-smart-contracts/core-contracts/blocklog.md rename to docs/content/references/iota-chains/core-contracts/blocklog.md diff --git a/docs/content/references/layer-2-smart-contracts/core-contracts/errors.md b/docs/content/references/iota-chains/core-contracts/errors.md similarity index 100% rename from docs/content/references/layer-2-smart-contracts/core-contracts/errors.md rename to docs/content/references/iota-chains/core-contracts/errors.md diff --git a/docs/content/references/layer-2-smart-contracts/core-contracts/evm.md b/docs/content/references/iota-chains/core-contracts/evm.md similarity index 100% rename from docs/content/references/layer-2-smart-contracts/core-contracts/evm.md rename to docs/content/references/iota-chains/core-contracts/evm.md diff --git a/docs/content/references/layer-2-smart-contracts/core-contracts/governance.md b/docs/content/references/iota-chains/core-contracts/governance.md similarity index 100% rename from docs/content/references/layer-2-smart-contracts/core-contracts/governance.md rename to docs/content/references/iota-chains/core-contracts/governance.md diff --git a/docs/content/references/layer-2-smart-contracts/core-contracts/overview.md b/docs/content/references/iota-chains/core-contracts/overview.md similarity index 100% rename from docs/content/references/layer-2-smart-contracts/core-contracts/overview.md rename to docs/content/references/iota-chains/core-contracts/overview.md diff --git a/docs/content/references/layer-2-smart-contracts/core-contracts/root.md b/docs/content/references/iota-chains/core-contracts/root.md similarity index 100% rename from docs/content/references/layer-2-smart-contracts/core-contracts/root.md rename to docs/content/references/iota-chains/core-contracts/root.md diff --git a/docs/content/references/layer-2-smart-contracts/core-contracts/xfer.md b/docs/content/references/iota-chains/core-contracts/xfer.md similarity index 100% rename from docs/content/references/layer-2-smart-contracts/core-contracts/xfer.md rename to docs/content/references/iota-chains/core-contracts/xfer.md diff --git a/docs/content/references/layer-2-smart-contracts/json-rpc-spec.md b/docs/content/references/iota-chains/json-rpc-spec.md similarity index 100% rename from docs/content/references/layer-2-smart-contracts/json-rpc-spec.md rename to docs/content/references/iota-chains/json-rpc-spec.md diff --git a/docs/content/references/layer-2-smart-contracts/magic-contract/introduction.md b/docs/content/references/iota-chains/magic-contract/introduction.md similarity index 100% rename from docs/content/references/layer-2-smart-contracts/magic-contract/introduction.md rename to docs/content/references/iota-chains/magic-contract/introduction.md diff --git a/docs/content/references/layer-2-smart-contracts/wasm-lib-data-types.mdx b/docs/content/references/iota-chains/wasm-lib-data-types.mdx similarity index 100% rename from docs/content/references/layer-2-smart-contracts/wasm-lib-data-types.mdx rename to docs/content/references/iota-chains/wasm-lib-data-types.mdx diff --git a/docs/content/sidebars/developer.js b/docs/content/sidebars/developer.js index 83a5230f34a..e2d3733080e 100644 --- a/docs/content/sidebars/developer.js +++ b/docs/content/sidebars/developer.js @@ -353,16 +353,16 @@ const developer = [ { type: 'category', - label: 'Solidity/EVM Smart Contracts', + label: 'IOTA Chains', link: { type: 'doc', - id: 'guides/developer/layer-2-smart-contracts/introduction', + id: 'guides/developer/iota-chains/introduction', }, items: [ { type: 'doc', label: 'Introduction', - id: 'guides/developer/layer-2-smart-contracts/introduction', + id: 'guides/developer/iota-chains/introduction', }, { type: 'category', @@ -371,19 +371,19 @@ const developer = [ { type: 'doc', label: 'Languages & VMs', - id: 'guides/developer/layer-2-smart-contracts/getting-started/languages-and-vms', + id: 'guides/developer/iota-chains/getting-started/languages-and-vms', }, - 'guides/developer/layer-2-smart-contracts/getting-started/quick-start', - 'guides/developer/layer-2-smart-contracts/getting-started/compatibility', + 'guides/developer/iota-chains/getting-started/quick-start', + 'guides/developer/iota-chains/getting-started/compatibility', { type: 'doc', label: 'Networks & Chains', - id: 'guides/developer/layer-2-smart-contracts/getting-started/networks-and-chains', + id: 'guides/developer/iota-chains/getting-started/networks-and-chains', }, { type: 'doc', label: 'Tools', - id: 'guides/developer/layer-2-smart-contracts/getting-started/tools', + id: 'guides/developer/iota-chains/getting-started/tools', }, ], }, @@ -391,46 +391,46 @@ const developer = [ type: 'category', label: 'How To', items: [ - 'guides/developer/layer-2-smart-contracts/how-tos/introduction', + 'guides/developer/iota-chains/how-tos/introduction', { type: 'doc', label: 'Send Funds from L1 to L2', - id: 'guides/developer/layer-2-smart-contracts/how-tos/send-funds-from-L1-to-L2', + id: 'guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2', }, { type: 'doc', label: 'Create a Basic Contract', - id: 'guides/developer/layer-2-smart-contracts/how-tos/create-a-basic-contract', + id: 'guides/developer/iota-chains/how-tos/create-a-basic-contract', }, { type: 'doc', label: 'Deploy a Smart Contract', - id: 'guides/developer/layer-2-smart-contracts/how-tos/deploy-a-smart-contract', + id: 'guides/developer/iota-chains/how-tos/deploy-a-smart-contract', }, { type: 'doc', label: 'Create Custom Tokens - ERC20', - id: 'guides/developer/layer-2-smart-contracts/how-tos/ERC20', + id: 'guides/developer/iota-chains/how-tos/ERC20', }, { type: 'doc', label: 'Send ERC20 Tokens Across Chains', - id: 'guides/developer/layer-2-smart-contracts/how-tos/send-ERC20-across-chains', + id: 'guides/developer/iota-chains/how-tos/send-ERC20-across-chains', }, { type: 'doc', label: 'Create NFTs - ERC721', - id: 'guides/developer/layer-2-smart-contracts/how-tos/ERC721', + id: 'guides/developer/iota-chains/how-tos/ERC721', }, { type: 'doc', label: 'Send NFTs Across Chains', - id: 'guides/developer/layer-2-smart-contracts/how-tos/send-NFTs-across-chains', + id: 'guides/developer/iota-chains/how-tos/send-NFTs-across-chains', }, { type: 'doc', label: 'Test Smart Contracts', - id: 'guides/developer/layer-2-smart-contracts/how-tos/test-smart-contracts', + id: 'guides/developer/iota-chains/how-tos/test-smart-contracts', }, { type: 'category', @@ -439,7 +439,7 @@ const developer = [ { type: 'doc', label: 'Introduction', - id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/introduction', + id: 'guides/developer/iota-chains/how-tos/core-contracts/introduction', }, { type: 'category', @@ -448,7 +448,7 @@ const developer = [ { type: 'doc', label: 'Get Native Assets Balance', - id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/get-balance', + id: 'guides/developer/iota-chains/how-tos/core-contracts/basics/get-balance', }, { type: 'category', @@ -457,24 +457,24 @@ const developer = [ { type: 'doc', label: 'Allow', - id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/allow', + id: 'guides/developer/iota-chains/how-tos/core-contracts/basics/allowance/allow', }, { type: 'doc', label: 'Get Allowance', - id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/get-allowance', + id: 'guides/developer/iota-chains/how-tos/core-contracts/basics/allowance/get-allowance', }, { type: 'doc', label: 'Take Allowance', - id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/allowance/take-allowance', + id: 'guides/developer/iota-chains/how-tos/core-contracts/basics/allowance/take-allowance', }, ], }, { type: 'doc', label: 'Send Assets to L1', - id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/basics/send-assets-to-l1', + id: 'guides/developer/iota-chains/how-tos/core-contracts/basics/send-assets-to-l1', }, ], }, @@ -485,32 +485,32 @@ const developer = [ { label: 'Introduction', type: 'doc', - id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/introduction', + id: 'guides/developer/iota-chains/how-tos/core-contracts/token/introduction', }, { type: 'doc', label: 'Create a Native Token', - id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/create-native-token', + id: 'guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token', }, { type: 'doc', label: 'Mint Native Tokens', - id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/mint-token', + id: 'guides/developer/iota-chains/how-tos/core-contracts/token/mint-token', }, { type: 'doc', label: 'Custom ERC20 Functions', - id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/erc20-native-token', + id: 'guides/developer/iota-chains/how-tos/core-contracts/token/erc20-native-token', }, { type: 'doc', label: 'Create a Foundry', - id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/create-foundry', + id: 'guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry', }, { type: 'doc', label: 'Register Token as ERC20', - id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/token/register-token', + id: 'guides/developer/iota-chains/how-tos/core-contracts/token/register-token', }, ], }, @@ -521,29 +521,29 @@ const developer = [ { label: 'Introduction', type: 'doc', - id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/introduction', + id: 'guides/developer/iota-chains/how-tos/core-contracts/nft/introduction', }, { type: 'doc', label: 'Mint an NFT', - id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/mint-nft', + id: 'guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft', }, { type: 'doc', label: 'Use as ERC721', - id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/nft/use-as-erc721', + id: 'guides/developer/iota-chains/how-tos/core-contracts/nft/use-as-erc721', }, ], }, { type: 'doc', label: 'Get Randomness on L2', - id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/get-randomness-on-l2', + id: 'guides/developer/iota-chains/how-tos/core-contracts/get-randomness-on-l2', }, { type: 'doc', label: 'Call and Call View', - id: 'guides/developer/layer-2-smart-contracts/how-tos/core-contracts/call-view', + id: 'guides/developer/iota-chains/how-tos/core-contracts/call-view', }, ], }, @@ -556,42 +556,42 @@ const developer = [ { type: 'doc', label: 'Anatomy of a Smart Contract', - id: 'guides/developer/layer-2-smart-contracts/explanations/smart-contract-anatomy', + id: 'guides/developer/iota-chains/explanations/smart-contract-anatomy', }, { type: 'doc', label: 'Sandbox Interface', - id: 'guides/developer/layer-2-smart-contracts/explanations/sandbox', + id: 'guides/developer/iota-chains/explanations/sandbox', }, { type: 'doc', label: 'Calling a Smart Contract', - id: 'guides/developer/layer-2-smart-contracts/explanations/invocation', + id: 'guides/developer/iota-chains/explanations/invocation', }, { type: 'doc', label: 'State, Transitions and State Anchoring', - id: 'guides/developer/layer-2-smart-contracts/explanations/states', + id: 'guides/developer/iota-chains/explanations/states', }, { type: 'doc', label: 'State manager', - id: 'guides/developer/layer-2-smart-contracts/explanations/state_manager', + id: 'guides/developer/iota-chains/explanations/state_manager', }, { type: 'doc', label: 'Validators and Access Nodes', - id: 'guides/developer/layer-2-smart-contracts/explanations/validators', + id: 'guides/developer/iota-chains/explanations/validators', }, { type: 'doc', label: 'Consensus', - id: 'guides/developer/layer-2-smart-contracts/explanations/consensus', + id: 'guides/developer/iota-chains/explanations/consensus', }, { type: 'doc', label: 'How Accounts Work', - id: 'guides/developer/layer-2-smart-contracts/explanations/how-accounts-work', + id: 'guides/developer/iota-chains/explanations/how-accounts-work', }, { type: 'link', @@ -606,7 +606,7 @@ const developer = [ items: [ { label: 'Getting Started', - id: 'guides/developer/layer-2-smart-contracts/solo/getting-started', + id: 'guides/developer/iota-chains/solo/getting-started', type: 'doc', }, { @@ -616,52 +616,52 @@ const developer = [ { type: 'doc', label: 'First Example', - id: 'guides/developer/layer-2-smart-contracts/solo/how-tos/first-example', + id: 'guides/developer/iota-chains/solo/how-tos/first-example', }, { type: 'doc', label: 'The L1 Ledger', - id: 'guides/developer/layer-2-smart-contracts/solo/how-tos/the-l1-ledger', + id: 'guides/developer/iota-chains/solo/how-tos/the-l1-ledger', }, { type: 'doc', label: 'Deploy a Smart Contract', - id: 'guides/developer/layer-2-smart-contracts/solo/how-tos/deploying-sc', + id: 'guides/developer/iota-chains/solo/how-tos/deploying-sc', }, { type: 'doc', label: 'Invoke a Smart Contract', - id: 'guides/developer/layer-2-smart-contracts/solo/how-tos/invoking-sc', + id: 'guides/developer/iota-chains/solo/how-tos/invoking-sc', }, { type: 'doc', label: 'Call a View', - id: 'guides/developer/layer-2-smart-contracts/solo/how-tos/view-sc', + id: 'guides/developer/iota-chains/solo/how-tos/view-sc', }, { type: 'doc', label: 'Error Handling', - id: 'guides/developer/layer-2-smart-contracts/solo/how-tos/error-handling', + id: 'guides/developer/iota-chains/solo/how-tos/error-handling', }, { type: 'doc', label: 'Accounts', - id: 'guides/developer/layer-2-smart-contracts/solo/how-tos/the-l2-ledger', + id: 'guides/developer/iota-chains/solo/how-tos/the-l2-ledger', }, { type: 'doc', label: 'Test Smart Contracts', - id: 'guides/developer/layer-2-smart-contracts/solo/how-tos/test', + id: 'guides/developer/iota-chains/solo/how-tos/test', }, { type: 'doc', label: 'Example Tests', - id: 'guides/developer/layer-2-smart-contracts/solo/how-tos/examples', + id: 'guides/developer/iota-chains/solo/how-tos/examples', }, { type: 'doc', label: 'Colored Tokens and Time Locks', - id: 'guides/developer/layer-2-smart-contracts/solo/how-tos/timelock', + id: 'guides/developer/iota-chains/solo/how-tos/timelock', }, ], }, @@ -674,12 +674,12 @@ const developer = [ { type: 'doc', label: 'The Schema Tool', - id: 'guides/developer/layer-2-smart-contracts/schema/introduction', + id: 'guides/developer/iota-chains/schema/introduction', }, { type: 'doc', label: 'Data Access Proxies', - id: 'guides/developer/layer-2-smart-contracts/schema/proxies', + id: 'guides/developer/iota-chains/schema/proxies', }, { type: 'category', @@ -688,82 +688,82 @@ const developer = [ { type: 'doc', label: 'Create a Schema', - id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/usage', + id: 'guides/developer/iota-chains/schema/how-tos/usage', }, { type: 'doc', label: 'Define the State', - id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/state', + id: 'guides/developer/iota-chains/schema/how-tos/state', }, { type: 'doc', label: 'Use Structured Data Types', - id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/structs', + id: 'guides/developer/iota-chains/schema/how-tos/structs', }, { type: 'doc', label: 'Generate Type Definitions', - id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/typedefs', + id: 'guides/developer/iota-chains/schema/how-tos/typedefs', }, { type: 'doc', label: 'Trigger Events', - id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/events', + id: 'guides/developer/iota-chains/schema/how-tos/events', }, { type: 'doc', label: 'Define Functions', - id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/funcs', + id: 'guides/developer/iota-chains/schema/how-tos/funcs', }, { type: 'doc', label: 'Limit Access', - id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/access', + id: 'guides/developer/iota-chains/schema/how-tos/access', }, { type: 'doc', label: 'Define Function Parameters', - id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/params', + id: 'guides/developer/iota-chains/schema/how-tos/params', }, { type: 'doc', label: 'Define Function Results', - id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/results', + id: 'guides/developer/iota-chains/schema/how-tos/results', }, { type: 'doc', label: 'Use Thunk Functions', - id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/thunks', + id: 'guides/developer/iota-chains/schema/how-tos/thunks', }, { type: 'doc', label: 'Use View-Only Functions', - id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/views', + id: 'guides/developer/iota-chains/schema/how-tos/views', }, { type: 'doc', label: 'Initialize a Smart Contract', - id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/init', + id: 'guides/developer/iota-chains/schema/how-tos/init', }, { type: 'doc', label: 'Transfer Tokens', - id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/transfers', + id: 'guides/developer/iota-chains/schema/how-tos/transfers', }, { type: 'doc', label: 'Add Function Descriptors', - id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/funcdesc', + id: 'guides/developer/iota-chains/schema/how-tos/funcdesc', }, { type: 'doc', label: 'Call Functions', - id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/call', + id: 'guides/developer/iota-chains/schema/how-tos/call', }, { type: 'doc', label: 'Post Asynchronous Requests', - id: 'guides/developer/layer-2-smart-contracts/schema/how-tos/post', + id: 'guides/developer/iota-chains/schema/how-tos/post', }, ], }, diff --git a/docs/content/sidebars/operator.js b/docs/content/sidebars/operator.js index 585df7c8539..a019f0a2d78 100644 --- a/docs/content/sidebars/operator.js +++ b/docs/content/sidebars/operator.js @@ -15,10 +15,10 @@ const operator = [ 'operator/node-tools', { type: 'category', - label: 'IOTA EVM Network', + label: 'IOTA Chains Node', link: { type: 'doc', - id: 'guides/operator/layer-2-smart-contracts-node/how-tos/running-a-node', + id: 'guides/operator/iota-chains-node/how-tos/running-a-node', }, items: [ { @@ -28,26 +28,26 @@ const operator = [ items: [ { type: 'doc', - id: 'guides/operator/layer-2-smart-contracts-node/how-tos/running-a-node', + id: 'guides/operator/iota-chains-node/how-tos/running-a-node', label: 'Run a Node', }, { type: 'doc', - id: 'guides/operator/layer-2-smart-contracts-node/how-tos/running-an-access-node', + id: 'guides/operator/iota-chains-node/how-tos/running-an-access-node', label: 'Run an Access Node', }, { - id: 'guides/operator/layer-2-smart-contracts-node/how-tos/wasp-cli', + id: 'guides/operator/iota-chains-node/how-tos/wasp-cli', label: 'Configure wasp-cli', type: 'doc', }, { - id: 'guides/operator/layer-2-smart-contracts-node/how-tos/setting-up-a-chain', + id: 'guides/operator/iota-chains-node/how-tos/setting-up-a-chain', label: 'Set Up a Chain', type: 'doc', }, { - id: 'guides/operator/layer-2-smart-contracts-node/how-tos/chain-management', + id: 'guides/operator/iota-chains-node/how-tos/chain-management', label: 'Manage a Chain', type: 'doc', }, @@ -59,11 +59,11 @@ const operator = [ items: [ { type: 'doc', - id: 'guides/operator/layer-2-smart-contracts-node/reference/configuration', + id: 'guides/operator/iota-chains-node/reference/configuration', }, { type: 'doc', - id: 'guides/operator/layer-2-smart-contracts-node/reference/metrics', + id: 'guides/operator/iota-chains-node/reference/metrics', }, ], }, diff --git a/docs/content/sidebars/references.js b/docs/content/sidebars/references.js index d5b0a3bd9bf..6198f120dcc 100644 --- a/docs/content/sidebars/references.js +++ b/docs/content/sidebars/references.js @@ -229,16 +229,16 @@ const references = [ }, { type: 'category', - label: 'Layer 2 Smart Contracts', + label: 'IOTA Chains', items: [ - 'references/layer-2-smart-contracts/json-rpc-spec', + 'references/iota-chains/json-rpc-spec', { type: 'category', label: 'Magic Contract', items: [ { type: 'autogenerated', - dirName: 'references/layer-2-smart-contracts/magic-contract', + dirName: 'references/iota-chains/magic-contract', }, ], }, @@ -249,42 +249,42 @@ const references = [ { type: 'doc', label: 'Overview', - id: 'references/layer-2-smart-contracts/core-contracts/overview', + id: 'references/iota-chains/core-contracts/overview', }, { type: 'doc', label: 'root', - id: 'references/layer-2-smart-contracts/core-contracts/root', + id: 'references/iota-chains/core-contracts/root', }, { type: 'doc', label: 'accounts', - id: 'references/layer-2-smart-contracts/core-contracts/accounts', + id: 'references/iota-chains/core-contracts/accounts', }, { type: 'doc', label: 'blob', - id: 'references/layer-2-smart-contracts/core-contracts/blob', + id: 'references/iota-chains/core-contracts/blob', }, { type: 'doc', label: 'blocklog', - id: 'references/layer-2-smart-contracts/core-contracts/blocklog', + id: 'references/iota-chains/core-contracts/blocklog', }, { type: 'doc', label: 'governance', - id: 'references/layer-2-smart-contracts/core-contracts/governance', + id: 'references/iota-chains/core-contracts/governance', }, { type: 'doc', label: 'errors', - id: 'references/layer-2-smart-contracts/core-contracts/errors', + id: 'references/iota-chains/core-contracts/errors', }, { type: 'doc', label: 'EVM', - id: 'references/layer-2-smart-contracts/core-contracts/evm', + id: 'references/iota-chains/core-contracts/evm', }, ], }, @@ -294,14 +294,14 @@ const references = [ items: [ { type: 'autogenerated', - dirName: 'references/layer-2-smart-contracts/iscutils', + dirName: 'references/iota-chains/iscutils', }, ], }, { type: 'doc', label: 'WasmLib Data Types', - id: 'references/layer-2-smart-contracts/wasm-lib-data-types', + id: 'references/iota-chains/wasm-lib-data-types', }, ], }, diff --git a/docs/site/package.json b/docs/site/package.json index 41b552eb633..97f047a8507 100644 --- a/docs/site/package.json +++ b/docs/site/package.json @@ -4,8 +4,8 @@ "private": true, "scripts": { "docusaurus": "docusaurus", - "dev": "docusaurus graphql-to-doc; rm '../content/references/iota-api/iota-graphql/reference/generated.md'; node src/utils/getopenrpcspecs.js; git clean -Xdf ../content/references/layer-2-smart-contracts/; ./scripts/get_wasp_references.sh; docusaurus start", - "build": "docusaurus graphql-to-doc; rm '../content/references/iota-api/iota-graphql/reference/generated.md'; node src/utils/getopenrpcspecs.js; git clean -Xdf ../content/references/layer-2-smart-contracts/; ./scripts/get_wasp_references.sh; docusaurus build", + "dev": "docusaurus graphql-to-doc; rm '../content/references/iota-api/iota-graphql/reference/generated.md'; node src/utils/getopenrpcspecs.js; git clean -Xdf ../content/references/iota-chains/; ./scripts/get-iota-chains-references.sh; docusaurus start", + "build": "docusaurus graphql-to-doc; rm '../content/references/iota-api/iota-graphql/reference/generated.md'; node src/utils/getopenrpcspecs.js; git clean -Xdf ../content/references/iota-chains/; ./scripts/get-iota-chains-references.sh; docusaurus build", "swizzle": "docusaurus swizzle", "deploy": "docusaurus deploy", "clear": "docusaurus clear", diff --git a/docs/site/scripts/get_wasp_references.sh b/docs/site/scripts/get-iota-chains-references.sh similarity index 69% rename from docs/site/scripts/get_wasp_references.sh rename to docs/site/scripts/get-iota-chains-references.sh index f784c60a511..15d66890023 100755 --- a/docs/site/scripts/get_wasp_references.sh +++ b/docs/site/scripts/get-iota-chains-references.sh @@ -6,10 +6,10 @@ cd tmp # Download and copy docs curl -sL https://s3.eu-central-1.amazonaws.com/files.iota.org/iota-wiki/wasp/1.3/iscmagic.tar.gz | tar xzv -cp -Rv docs/iscmagic/* ../../content/references/layer-2-smart-contracts/magic-contract/ +cp -Rv docs/iscmagic/* ../../content/references/iota-chains/magic-contract/ curl -sL https://s3.eu-central-1.amazonaws.com/files.iota.org/iota-wiki/wasp/1.3/iscutils.tar.gz | tar xzv -cp -Rv docs/iscutils ../../content/references/layer-2-smart-contracts/ +cp -Rv docs/iscutils ../../content/references/iota-chains/ # Return to root and cleanup cd - From 4c60940dacb220d1f9c45375d5837fcb3adc3341 Mon Sep 17 00:00:00 2001 From: Jeroen van den Hout Date: Mon, 10 Jun 2024 22:28:32 +0200 Subject: [PATCH 12/37] feat(docs): add ISC images --- .../explanations/how-accounts-work.md | 4 ++-- .../iota-chains/explanations/sandbox.md | 4 ++-- .../explanations/smart-contract-anatomy.md | 4 ++-- .../iota-chains/explanations/states.md | 6 +++--- .../getting-started/languages-and-vms.md | 4 ++-- .../iota-chains/getting-started/tools.mdx | 4 ++-- .../developer/iota-chains/how-tos/ERC20.md | 6 +++--- .../developer/iota-chains/how-tos/ERC721.md | 8 +++---- .../how-tos/deploy-a-smart-contract.mdx | 2 +- .../how-tos/send-funds-from-L1-to-L2.mdx | 20 +++++++++--------- .../developer/iota-chains/introduction.md | 4 ++-- .../developer/iota-chains/schema/proxies.mdx | 4 ++-- .../iota-chains/solo/how-tos/deploying-sc.md | 2 +- .../iota-chains/solo/how-tos/invoking-sc.md | 4 ++-- .../iota-chains/solo/how-tos/view-sc.md | 4 ++-- docs/site/static/img/banner/banner_wasp.png | Bin 0 -> 14704 bytes ...banner_wasp_core_concepts_architecture.png | Bin 0 -> 30264 bytes ...ner_wasp_core_concepts_smart_contracts.png | Bin 0 -> 18257 bytes .../banner_wasp_core_contracts_overview.png | Bin 0 -> 17441 bytes .../img/banner/banner_wasp_using_docker.png | Bin 0 -> 22157 bytes docs/site/static/img/iota-chains/chain0.png | Bin 0 -> 18542 bytes docs/site/static/img/iota-chains/chain1.png | Bin 0 -> 80411 bytes .../img/iota-chains/evm/examples/compile.png | Bin 0 -> 96554 bytes .../evm/examples/deploy-metamask.png | Bin 0 -> 38508 bytes .../img/iota-chains/evm/examples/deploy.png | Bin 0 -> 105145 bytes .../evm/examples/erc20-balance.png | Bin 0 -> 36709 bytes .../examples/explorer-contract-address.png | Bin 0 -> 119451 bytes .../how-tos/ERC20/metamask-erc20-balance.png | Bin 0 -> 36723 bytes ...et-transaction-or-go-to-block-explorer.png | Bin 0 -> 34819 bytes .../how-tos/ERC20/metamask-import-tokens.png | Bin 0 -> 35602 bytes .../how-tos/ERC721/confirm-in-metamask.png | Bin 0 -> 32083 bytes .../evm/how-tos/ERC721/safe-mint.png | Bin 0 -> 14526 bytes .../evm/how-tos/ERC721/set-initial-owner.png | Bin 0 -> 26683 bytes .../get-funds/bloom/bloom-click-on-send.png | Bin 0 -> 12257 bytes .../bloom/bloom-review-and-confirm.png | Bin 0 -> 25871 bytes .../bloom/bloom-select-evm-account-1.png | Bin 0 -> 23275 bytes .../bloom/bloom-select-the-desired-amount.png | Bin 0 -> 17802 bytes .../get-funds/bloom/enter-the-amount.png | Bin 0 -> 21432 bytes .../bloom/enter-the-recipient-address.png | Bin 0 -> 26933 bytes .../review-and-confirm-the-transaction.png | Bin 0 -> 30691 bytes .../how-tos/get-funds/bloom/select-send.png | Bin 0 -> 14862 bytes .../get-funds/bloom/select-the-smr-token.png | Bin 0 -> 29704 bytes .../how-tos/get-funds/copy-your-address.png | Bin 0 -> 32293 bytes ...ur-desired-amount-and-metamask-address.png | Bin 0 -> 31966 bytes .../how-tos/get-funds/firefly/hit-send.png | Bin 0 -> 37053 bytes .../get-funds/firefly/select-send-assets.png | Bin 0 -> 23432 bytes .../get-funds/firefly/select-shimmer-evm.png | Bin 0 -> 30875 bytes .../img/iota-chains/evm/remix-deployed.png | Bin 0 -> 58299 bytes .../evm/remix-injected-provider-metamask.png | Bin 0 -> 38347 bytes .../evm/remix-injected-provider-set.png | Bin 0 -> 28820 bytes .../iota-chains/evm/remix-metamask-detail.png | Bin 0 -> 99932 bytes .../img/iota-chains/evm/remix-vm-injected.png | Bin 0 -> 89635 bytes .../static/img/iota-chains/multichain.png | Bin 0 -> 38994 bytes docs/site/static/img/iota-chains/sandbox.png | Bin 0 -> 43865 bytes .../img/iota-chains/tutorial/SC-structure.png | Bin 0 -> 41452 bytes .../img/iota-chains/tutorial/accounts.png | Bin 0 -> 62709 bytes .../img/iota-chains/tutorial/call_view.png | Bin 0 -> 49904 bytes .../img/iota-chains/tutorial/send_request.png | Bin 0 -> 53575 bytes .../img/iota-chains/wasm_vm/IscHost.png | Bin 0 -> 16511 bytes .../img/iota-chains/wasm_vm/Proxies.png | Bin 0 -> 24052 bytes .../static/img/iota-chains/wasm_vm/WasmVM.png | Bin 0 -> 18482 bytes docs/site/static/logo/WASP_logo_dark.png | Bin 0 -> 20128 bytes docs/site/static/logo/WASP_logo_light.png | Bin 0 -> 20057 bytes 63 files changed, 40 insertions(+), 40 deletions(-) create mode 100644 docs/site/static/img/banner/banner_wasp.png create mode 100644 docs/site/static/img/banner/banner_wasp_core_concepts_architecture.png create mode 100644 docs/site/static/img/banner/banner_wasp_core_concepts_smart_contracts.png create mode 100644 docs/site/static/img/banner/banner_wasp_core_contracts_overview.png create mode 100644 docs/site/static/img/banner/banner_wasp_using_docker.png create mode 100644 docs/site/static/img/iota-chains/chain0.png create mode 100644 docs/site/static/img/iota-chains/chain1.png create mode 100644 docs/site/static/img/iota-chains/evm/examples/compile.png create mode 100644 docs/site/static/img/iota-chains/evm/examples/deploy-metamask.png create mode 100644 docs/site/static/img/iota-chains/evm/examples/deploy.png create mode 100644 docs/site/static/img/iota-chains/evm/examples/erc20-balance.png create mode 100644 docs/site/static/img/iota-chains/evm/examples/explorer-contract-address.png create mode 100644 docs/site/static/img/iota-chains/evm/how-tos/ERC20/metamask-erc20-balance.png create mode 100644 docs/site/static/img/iota-chains/evm/how-tos/ERC20/metamask-get-transaction-or-go-to-block-explorer.png create mode 100644 docs/site/static/img/iota-chains/evm/how-tos/ERC20/metamask-import-tokens.png create mode 100644 docs/site/static/img/iota-chains/evm/how-tos/ERC721/confirm-in-metamask.png create mode 100644 docs/site/static/img/iota-chains/evm/how-tos/ERC721/safe-mint.png create mode 100644 docs/site/static/img/iota-chains/evm/how-tos/ERC721/set-initial-owner.png create mode 100644 docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/bloom-click-on-send.png create mode 100644 docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/bloom-review-and-confirm.png create mode 100644 docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/bloom-select-evm-account-1.png create mode 100644 docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/bloom-select-the-desired-amount.png create mode 100644 docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/enter-the-amount.png create mode 100644 docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/enter-the-recipient-address.png create mode 100644 docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/review-and-confirm-the-transaction.png create mode 100644 docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/select-send.png create mode 100644 docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/select-the-smr-token.png create mode 100644 docs/site/static/img/iota-chains/evm/how-tos/get-funds/copy-your-address.png create mode 100644 docs/site/static/img/iota-chains/evm/how-tos/get-funds/firefly/enter-your-desired-amount-and-metamask-address.png create mode 100644 docs/site/static/img/iota-chains/evm/how-tos/get-funds/firefly/hit-send.png create mode 100644 docs/site/static/img/iota-chains/evm/how-tos/get-funds/firefly/select-send-assets.png create mode 100644 docs/site/static/img/iota-chains/evm/how-tos/get-funds/firefly/select-shimmer-evm.png create mode 100644 docs/site/static/img/iota-chains/evm/remix-deployed.png create mode 100644 docs/site/static/img/iota-chains/evm/remix-injected-provider-metamask.png create mode 100644 docs/site/static/img/iota-chains/evm/remix-injected-provider-set.png create mode 100644 docs/site/static/img/iota-chains/evm/remix-metamask-detail.png create mode 100644 docs/site/static/img/iota-chains/evm/remix-vm-injected.png create mode 100644 docs/site/static/img/iota-chains/multichain.png create mode 100644 docs/site/static/img/iota-chains/sandbox.png create mode 100644 docs/site/static/img/iota-chains/tutorial/SC-structure.png create mode 100644 docs/site/static/img/iota-chains/tutorial/accounts.png create mode 100644 docs/site/static/img/iota-chains/tutorial/call_view.png create mode 100644 docs/site/static/img/iota-chains/tutorial/send_request.png create mode 100644 docs/site/static/img/iota-chains/wasm_vm/IscHost.png create mode 100644 docs/site/static/img/iota-chains/wasm_vm/Proxies.png create mode 100644 docs/site/static/img/iota-chains/wasm_vm/WasmVM.png create mode 100644 docs/site/static/logo/WASP_logo_dark.png create mode 100644 docs/site/static/logo/WASP_logo_light.png diff --git a/docs/content/guides/developer/iota-chains/explanations/how-accounts-work.md b/docs/content/guides/developer/iota-chains/explanations/how-accounts-work.md index 8847cb2c883..15809f5d2dd 100644 --- a/docs/content/guides/developer/iota-chains/explanations/how-accounts-work.md +++ b/docs/content/guides/developer/iota-chains/explanations/how-accounts-work.md @@ -1,7 +1,7 @@ --- description: 'IOTA Smart Contracts chains keep a ledger of on-chain account balances. On-chain accounts are identified by an AgentID.' -image: /img/tutorial/accounts.png +image: /img/iota-chains/tutorial/accounts.png tags: - smart contracts @@ -86,7 +86,7 @@ By calling this contract, it is possible to: The following diagram illustrates an example situation. The IDs and hnames are shortened for simplicity. -[![Example situation. Two chains are deployed, with three smart contracts and one address.](/img/tutorial/accounts.png)](/img/tutorial/accounts.png) +[![Example situation. Two chains are deployed, with three smart contracts and one address.](/img/iota-chains/tutorial/accounts.png)](/img/iota-chains/tutorial/accounts.png) Two chains are deployed, with IDs `chainA` and `chainB`. `chainA` has two smart contracts on it (with hnames `3037` and `2225`), and `chainB` has one smart contract (`7003`). diff --git a/docs/content/guides/developer/iota-chains/explanations/sandbox.md b/docs/content/guides/developer/iota-chains/explanations/sandbox.md index d5ff9a7add4..dffa9648862 100644 --- a/docs/content/guides/developer/iota-chains/explanations/sandbox.md +++ b/docs/content/guides/developer/iota-chains/explanations/sandbox.md @@ -1,7 +1,7 @@ --- description: 'Smart Contracts can only interact with the world by using the Sandbox interface which provides limited and deterministic access to the state through a key/value storage abstraction.' -image: /img/sandbox.png +image: /img/iota-chains/sandbox.png tags: - smart contracts @@ -26,7 +26,7 @@ Instead of working on the state as a whole, each smart contract can only modify The only way for smart contracts to access data is to use the sandbox interface, which is deterministic. It provides their internal state as a list of key/value pairs. -![Sandbox](/img/sandbox.png) +![Sandbox](/img/iota-chains/sandbox.png) Besides reading and writing to the contract state, the Sandbox interface allows smart contracts to access: diff --git a/docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md b/docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md index aa5539626a9..db01895d106 100644 --- a/docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md +++ b/docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md @@ -1,6 +1,6 @@ --- description: Each smart contract instance has a program with a collection of entry points and a state. -image: /img/tutorial/SC-structure.png +image: /img/iota-chains/tutorial/SC-structure.png tags: - smart contracts - structure @@ -19,7 +19,7 @@ It can support different _VM types_ (i.e., interpreters) simultaneously on the s For example, it is possible to have [Wasm](../getting-started/languages-and-vms.md#wasm-vm-for-isc) and [EVM/Solidity](../getting-started/languages-and-vms.md#evmsolidity-based-smart-contracts) smart contracts coexisting on the same chain. -![Smart Contract Structure](/img/tutorial/SC-structure.png) +![Smart Contract Structure](/img/iota-chains/tutorial/SC-structure.png) ## Identifying a Smart Contract diff --git a/docs/content/guides/developer/iota-chains/explanations/states.md b/docs/content/guides/developer/iota-chains/explanations/states.md index 819068b9aaf..d44deacc87f 100644 --- a/docs/content/guides/developer/iota-chains/explanations/states.md +++ b/docs/content/guides/developer/iota-chains/explanations/states.md @@ -1,7 +1,7 @@ --- description: 'The state of the chain consists of balances of native IOTA digital assets and a collection of key/value pairs which represents use case-specific data stored in the chain by its smart contracts outside the UTXO ledger.' -image: /img/chain0.png +image: /img/iota-chains/chain0.png tags: - state @@ -107,7 +107,7 @@ produces the next one. The transaction includes the movement of the chain's asse At any moment in time, the data state of the chain is a result of applying the historical sequence of blocks, starting from the empty data state. -![State transitions](/img/chain0.png) +![State transitions](/img/iota-chains/chain0.png) On the L1 UTXO ledger, the state's history is represented as a sequence (chain) of UTXOs, each holding the chain’s assets in a particular state and the anchoring hash of the data state. @@ -119,4 +119,4 @@ state hash). The ISC virtual machine (VM) computes the blocks and state outputs that anchor the state, which ensures that the state transitions are calculated deterministically and consistently. -![Chain](/img/chain1.png) +![Chain](/img/iota-chains/chain1.png) diff --git a/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.md b/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.md index 1719a69053f..16fcd5fba36 100644 --- a/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.md +++ b/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.md @@ -47,13 +47,13 @@ IOTA Smart Contracts (ISC) provide a sandboxed environment through an API, facil interactions with ISC functions. This API supports any Virtual Machine (VM) aiming to build a system for smart contract code execution on ISC. -![Wasp node ISC Host](/img/wasm_vm/IscHost.png) +![Wasp node ISC Host](/img/iota-chains/wasm_vm/IscHost.png) You can use a [WebAssembly (Wasm)](https://webassembly.org/) VM as a compilation target, facilitated by the open-source [Wasmtime runtime](https://wasmtime.dev/). This setup encourages dynamic smart contract operations compiled to Wasm code, promoting security and adaptability with different programming languages. -![Wasm VM](/img/wasm_vm/WasmVM.png) +![Wasm VM](/img/iota-chains/wasm_vm/WasmVM.png) The Wasm VM operates with self-contained `WasmLib` libraries linked to individual Wasm codes, optimizing the ISC sandbox functionality and smart contract state storage access. diff --git a/docs/content/guides/developer/iota-chains/getting-started/tools.mdx b/docs/content/guides/developer/iota-chains/getting-started/tools.mdx index d2150465845..9f599ff7c09 100644 --- a/docs/content/guides/developer/iota-chains/getting-started/tools.mdx +++ b/docs/content/guides/developer/iota-chains/getting-started/tools.mdx @@ -151,14 +151,14 @@ should set the environment as **Injected Provider - Metamask**, which should the Click on the _Deploy & Run transactions_ button in the menu on the left and select `Injected Web3` from the `Environment` dropdown. -![Select Injected Provider from the Environment dropdown](/img/evm/remix-injected-provider-metamask.png) +![Select Injected Provider from the Environment dropdown](/img/iota-chains/evm/remix-injected-provider-metamask.png) Metamask will ask to connect to Remix, and once connected, it will set the `Environment` to `Injected Web3` with the "Custom (Chain ID) network". -![Environment will be set to Injected Web3](/img/evm/remix-injected-provider-set.png)] +![Environment will be set to Injected Web3](/img/iota-chains/evm/remix-injected-provider-set.png)] ## Hardhat diff --git a/docs/content/guides/developer/iota-chains/how-tos/ERC20.md b/docs/content/guides/developer/iota-chains/how-tos/ERC20.md index adf0a6ccfa1..7afe3f22c44 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/ERC20.md +++ b/docs/content/guides/developer/iota-chains/how-tos/ERC20.md @@ -78,17 +78,17 @@ Once you have deployed your contract, you can add your new custom token to your [ShimmerEVM Explorer](https://explorer.evm.testnet.shimmer.network/) or [EVM Testnet Explorer](https://explorer.evm.testnet.shimmer.network/) and use the search bar to find transaction. -!['View on block explorer](/img/evm/how-tos/ERC20/metamask-get-transaction-or-go-to-block-explorer.png) +!['View on block explorer](/img/iota-chains/evm/how-tos/ERC20/metamask-get-transaction-or-go-to-block-explorer.png) 2. Copy the contract address from the transaction details, and import your custom ERC20 tokens into MetaMask. -![Copy contract address](/img/evm/how-tos/ERC20/metamask-import-tokens.png) +![Copy contract address](/img/iota-chains/evm/how-tos/ERC20/metamask-import-tokens.png) ## 3. Have some Fun Now you should see your token in MetaMask. You can send them to your friends without any fees or gas costs. -![Copy contract address](/img/evm/how-tos/ERC20/metamask-erc20-balance.png) +![Copy contract address](/img/iota-chains/evm/how-tos/ERC20/metamask-erc20-balance.png) You also can ask in the [Discord Chat Server](https://discord.iota.org) to send them around and discover what the community is building on IOTA Smart Contracts. diff --git a/docs/content/guides/developer/iota-chains/how-tos/ERC721.md b/docs/content/guides/developer/iota-chains/how-tos/ERC721.md index 767661dbff2..432b2e07b75 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/ERC721.md +++ b/docs/content/guides/developer/iota-chains/how-tos/ERC721.md @@ -1,6 +1,6 @@ --- description: Create and deploy a Solidity smart contract to mint NFTs using the ERC721 standard. -image: /img/evm/ozw-721.png +image: /img/iota-chains/evm/ozw-721.png tags: - smart contracts - EVM @@ -103,7 +103,7 @@ directly. Before you can deploy this contract, you will need to set the `Initial Owner` address; this can be your own IOTA EVM address. -!["Set the initial owner" img.png](/img/evm/how-tos/ERC721/set-initial-owner.png) +!["Set the initial owner" img.png](/img/iota-chains/evm/how-tos/ERC721/set-initial-owner.png) ::: @@ -117,11 +117,11 @@ To do, you should: 1. Open the contract (listed under `Deployed Contracts`). 2. Insert your target IOTA EVM in beside the `safeMint` button and then click the button. - ![Safe mint](/img/evm/how-tos/ERC721/safe-mint.png) + ![Safe mint](/img/iota-chains/evm/how-tos/ERC721/safe-mint.png) 3. Confirm the transaction on Metamask. - ![Confirm in metamask](/img/evm/how-tos/ERC721/confirm-in-metamask.png) + ![Confirm in metamask](/img/iota-chains/evm/how-tos/ERC721/confirm-in-metamask.png) If you visit your address in the visit the [IOTA EVM Explorer](https://explorer.evm.iota.org), [ShimmerEVM Explorer](https://explorer.evm.testnet.shimmer.network/) or [EVM Testnet Explorer](https://explorer.evm.testnet.shimmer.network/) diff --git a/docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx b/docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx index 0a1860715ec..ca9ab2d3d9d 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx @@ -70,7 +70,7 @@ Open your web browser and navigate to [Remix IDE](https://remix.ethereum.org/). 1. Switch to the "Deploy & Run Transactions" tab on the left sidebar. 2. In the "Environment" dropdown, select and select `Injected Web3` from the `Environment` dropdown. - ![Select Injected Provider from the Environment dropdown](/img/evm/remix-injected-provider-metamask.png) + ![Select Injected Provider from the Environment dropdown](/img/iota-chains/evm/remix-injected-provider-metamask.png) 3. After selecting the environment, make sure the contract Counter is selected in the `Contract` dropdown. 4. Click the `Deploy` button. If you're using an Ethereum network, confirm the transaction in your Web3 wallet. diff --git a/docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx b/docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx index 0b1b47dec7f..03d90948280 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx @@ -53,23 +53,23 @@ You can use your [Firefly Wallet](https://firefly.iota.org/) to easily send L1 I 2. Once you have added the EVM to Metamask, you can get your address: - ![Copy your Metamask address](/img/evm/how-tos/get-funds/copy-your-address.png) + ![Copy your Metamask address](/img/iota-chains/evm/how-tos/get-funds/copy-your-address.png) 3. Next, you will need to open your [Firefly Wallet](https://firefly.iota.org/) and click on `Send Assets`. - ![Click send assets](/img/evm/how-tos/get-funds/firefly/select-send-assets.png) + ![Click send assets](/img/iota-chains/evm/how-tos/get-funds/firefly/select-send-assets.png) 4. Select the EVM chain you want to use in the network dropdown. - ![Select the EVM network](/img/evm/how-tos/get-funds/firefly/select-shimmer-evm.png) + ![Select the EVM network](/img/iota-chains/evm/how-tos/get-funds/firefly/select-shimmer-evm.png) 5. Enter the amount of tokens you want to transfer, and the Metamask address from step 2, and click on `Next` - ![Enter the amount of tokens and metamask address](/img/evm/how-tos/get-funds/firefly/enter-your-desired-amount-and-metamask-address.png) + ![Enter the amount of tokens and metamask address](/img/iota-chains/evm/how-tos/get-funds/firefly/enter-your-desired-amount-and-metamask-address.png) 6. Review the transaction details and click on `Send`. - ![Hit Send](/img/evm/how-tos/get-funds/firefly/hit-send.png) + ![Hit Send](/img/iota-chains/evm/how-tos/get-funds/firefly/hit-send.png) @@ -79,24 +79,24 @@ You can use your [Bloom Wallet](https://bloomwallet.io/) to easily send L1 base 1. First, you will need to open your [Bloom Wallet](https://firefly.iota.org/) and click on `Send`. - ![Click send](/img/evm/how-tos/get-funds/bloom/select-send.png) + ![Click send](/img/iota-chains/evm/how-tos/get-funds/bloom/select-send.png) 2. Select an account with base tokens. - ![Select an account with base tokens](/img/evm/how-tos/get-funds/bloom/select-the-smr-token.png) + ![Select an account with base tokens](/img/iota-chains/evm/how-tos/get-funds/bloom/select-the-smr-token.png) 3. Bloom will automatically create an EVM address for you, so you can send funds to that address from the EVM dropdown. Alternatively, you can input any other EVM address. - ![Select you EVM Address](/img/evm/how-tos/get-funds/bloom/enter-the-recipient-address.png) + ![Select you EVM Address](/img/iota-chains/evm/how-tos/get-funds/bloom/enter-the-recipient-address.png) 4. Enter the amount of base tokens you want to transfer. - ![Enter the amount of base tokens you want to transfer](/img/evm/how-tos/get-funds/bloom/enter-the-amount.png) + ![Enter the amount of base tokens you want to transfer](/img/iota-chains/evm/how-tos/get-funds/bloom/enter-the-amount.png) 5. Review the transaction details and click on `Confirm`. - ![Hit Send](/img/evm/how-tos/get-funds/bloom/review-and-confirm-the-transaction.png) + ![Hit Send](/img/iota-chains/evm/how-tos/get-funds/bloom/review-and-confirm-the-transaction.png) \ No newline at end of file diff --git a/docs/content/guides/developer/iota-chains/introduction.md b/docs/content/guides/developer/iota-chains/introduction.md index b3811792692..28b9d0a7bd7 100644 --- a/docs/content/guides/developer/iota-chains/introduction.md +++ b/docs/content/guides/developer/iota-chains/introduction.md @@ -37,7 +37,7 @@ As validator nodes execute the smart contracts, they tally these state changes a In turn ISC chains, each with their state and smart contracts, update their state collectively and interact with Layer 1 and other L2 chains, offering a sophisticated multi-chain architecture. -![IOTA Smart Contacts multichain architecture](/img/multichain.png 'Click to see the full-size image.') +![IOTA Smart Contacts multichain architecture](/img/iota-chains/multichain.png 'Click to see the full-size image.') _IOTA Smart Contacts multichain architecture._ @@ -55,7 +55,7 @@ ISC Smart contracts can access the [Sandbox interface](explanations/sandbox.md). This interface provides access to the chain state, native assets, allows interaction with other contracts/chains, as well as various utilities like cryptographic functions and event dispatching. -![Sandbox](/img/sandbox.png) +![Sandbox](/img/iota-chains/sandbox.png) ## Calling a Smart Contract diff --git a/docs/content/guides/developer/iota-chains/schema/proxies.mdx b/docs/content/guides/developer/iota-chains/schema/proxies.mdx index 0459da5c0bf..2b2a0f5c7ec 100644 --- a/docs/content/guides/developer/iota-chains/schema/proxies.mdx +++ b/docs/content/guides/developer/iota-chains/schema/proxies.mdx @@ -9,7 +9,7 @@ tags: - map proxies - explanation description: As there is no way for the Wasm code to access any memory outside its own memory space, the WasmLib interface provides a number of proxies to make accessing data within the ISC sandbox as seamless as possible. -image: /img/wasm_vm/Proxies.png +image: /img/iota-chains/wasm_vm/Proxies.png --- # Data Access Proxies @@ -67,7 +67,7 @@ They use JSON and YAML nesting patterns, and there are two primary types: ## Proxies in Action -![Proxies in WasmLib](/img/wasm_vm/Proxies.png) +![Proxies in WasmLib](/img/iota-chains/wasm_vm/Proxies.png) In the illustration, we see the key-value combinations (Key 1 to Key 4) in the ISC state storage map. Key 4 directs us to an array containing indexed values ranging from 0 to N. diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/deploying-sc.md b/docs/content/guides/developer/iota-chains/solo/how-tos/deploying-sc.md index 387e4d18235..33534aae023 100644 --- a/docs/content/guides/developer/iota-chains/solo/how-tos/deploying-sc.md +++ b/docs/content/guides/developer/iota-chains/solo/how-tos/deploying-sc.md @@ -1,6 +1,6 @@ --- description: Deploying Wasm smart contracts with Solo. -image: /img/tutorial/send_request.png +image: /img/iota-chains/tutorial/send_request.png tags: - testing - PostRequestSync diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/invoking-sc.md b/docs/content/guides/developer/iota-chains/solo/how-tos/invoking-sc.md index ec60f2d2cbe..5a502cac050 100644 --- a/docs/content/guides/developer/iota-chains/solo/how-tos/invoking-sc.md +++ b/docs/content/guides/developer/iota-chains/solo/how-tos/invoking-sc.md @@ -1,6 +1,6 @@ --- description: Invoking smart contracts with on-ledger and off-ledger requests with Solo. -image: /img/tutorial/send_request.png +image: /img/iota-chains/tutorial/send_request.png tags: - how-to - explanation @@ -62,7 +62,7 @@ not necessary to manually deposit more funds for gas. ## On-Ledger Requests -[![Generic process of posting an on-ledger request to the smart contract](/img/tutorial/send_request.png)](/img/tutorial/send_request.png) +[![Generic process of posting an on-ledger request to the smart contract](/img/iota-chains/tutorial/send_request.png)](/img/iota-chains/tutorial/send_request.png) The diagram above depicts the generic process of posting an _on-ledger_ request to the smart contract. The same diagram is valid for the Solo environment and any other requester that sends an on-ledger request, e.g., the diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/view-sc.md b/docs/content/guides/developer/iota-chains/solo/how-tos/view-sc.md index 2bac649b39e..df59550462a 100644 --- a/docs/content/guides/developer/iota-chains/solo/how-tos/view-sc.md +++ b/docs/content/guides/developer/iota-chains/solo/how-tos/view-sc.md @@ -1,6 +1,6 @@ --- description: Calling smart contract view functions with Solo. -image: /img/tutorial/call_view.png +image: /img/iota-chains/tutorial/call_view.png tags: - how to - testing @@ -22,7 +22,7 @@ res, err := chain.CallView("example1", "getString") The call returns a collection of key/value pairs `res` and an error result `err` in the typical Go fashion. -[![Calling a view process](/img/tutorial/call_view.png)](/img/tutorial/call_view.png) +[![Calling a view process](/img/iota-chains/tutorial/call_view.png)](/img/iota-chains/tutorial/call_view.png) The basic principle of calling a view is similar to sending a request to the smart contract. The essential difference is that calling a view does not constitute an asynchronous transaction; it is just a direct synchronous call to the view diff --git a/docs/site/static/img/banner/banner_wasp.png b/docs/site/static/img/banner/banner_wasp.png new file mode 100644 index 0000000000000000000000000000000000000000..a1348ded18761733f3ceb89f100c43b547bc1aee GIT binary patch literal 14704 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%0AKz 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 literal 0 HcmV?d00001 diff --git a/docs/site/static/img/banner/banner_wasp_using_docker.png b/docs/site/static/img/banner/banner_wasp_using_docker.png new file mode 100644 index 0000000000000000000000000000000000000000..34ed36b8455b8f65e397045a8d4e3a32767d2730 GIT binary patch literal 22157 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 literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/evm/examples/compile.png b/docs/site/static/img/iota-chains/evm/examples/compile.png new file mode 100644 index 0000000000000000000000000000000000000000..6c4bb12e1c8c505859f833ddd54d0e7f2a03f70e GIT binary patch literal 96554 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 literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/evm/examples/deploy-metamask.png b/docs/site/static/img/iota-chains/evm/examples/deploy-metamask.png new file mode 100644 index 0000000000000000000000000000000000000000..8395cd68268bccf68295e60fad96198252439f41 GIT binary patch literal 38508 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 I#Yo9)7|w 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 K(~|SQ-u)kTp8Dnh literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/evm/examples/erc20-balance.png b/docs/site/static/img/iota-chains/evm/examples/erc20-balance.png new file mode 100644 index 0000000000000000000000000000000000000000..ec88a5cff26b8e566027e997b98a94c6c9ef473d GIT binary patch literal 36709 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

g4l+%{$QQG64nRG~-a*eb1yXzCJ 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�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�UptMItRIRnY6=a17ExogdxtYL`!$&8*m7U>R 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 axS?#g#!69yod_e~&ubCMm)SxezWgUs&Vd*J literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/evm/how-tos/ERC20/metamask-import-tokens.png b/docs/site/static/img/iota-chains/evm/how-tos/ERC20/metamask-import-tokens.png new file mode 100644 index 0000000000000000000000000000000000000000..65cc8c9774dd6b87a1ba86c908dffd3c232c7d0c GIT binary patch literal 35602 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 QD?w9H(2y^aegEly0HYWu)c^nh literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/bloom-select-evm-account-1.png b/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/bloom-select-evm-account-1.png new file mode 100644 index 0000000000000000000000000000000000000000..4938d9a7eed2ad4618115c78d913d957265c0c06 GIT binary patch literal 23275 zcmcG$byQW+_b+-d07;eZ21UBNLt469y1PR`kQPunBqR>q-6BfEp%2~Nop15|-FV~P zKi(U6yvG;}4}0&k*WPQ*HRor3=4TrAK~WkVg%AY-fuPI0mr#K~5Mba}7a0*8i6;4o z5B_=PA||7T41Ro(KYj&&6SzuhxvDytyLuQqn?Wq>9qh~)T}++L%Q{O_`AaDiLbyhdGc}k5Yx8{|F)BK zf?xJQ8iaucW#aj;_|$j=OJs`Rm)Wjr5OsAH{79|i%5UU2V#pM|QqNg7(X|+PdD1bI zCaHp7ijDC=4f3U79JX8$`8Kb>CDzpH4#TE3>z<7mkGJ@vvgclec7Ostul<~{^~xv} z1-C93Q5)Dgbwvl)OGM>)H$omS&5LLG&lobDYT%MLbT3pNkET(}e|ahP)j96}_~fY1 zf9}6*t)?ET=pd30%YpJ?caLL^anLE|KMn1Q?y^7GtZJZn97jzK3hgpF6)WS$Z7@() zbLGQHAB0G;yEoyaat={t(Hql)N17QSl24MKH-k$%NR)A#RID1+Y10>0X8+@TeB$x& zj!pG-@|L)Nt5M+7C!8Phoz>s-?pTtm$9UYkOUs7cea?2JbgYT33Z2kM$J&1HwX_T{ zqzT8HI`KCg%sb)eM7$L9Oqn<8wB$%^BFPzvoHv37hRgQk7!zV+|0R0xOjaODaG`V} z3+r(|fsZ!Kx^38Pp7ALqXfS!VM2C{5wL8dd#5uZh|C717GF@>t@LsZdVm(f;2`90) zmEKU~Uf$X13c{RK6~&qKT{&nC+MpBqH%!6p(}+#+n^Q$yzri~lS=})Y|DR z@7et^VtF~o5^j;<9~rfi_zDZQnF3#^@(@0H5oVe4r}--4UFjjA{q3B`VOntEOHLhS z@u~rxS&=?2JK5Pf_0(Dpn~`iaI}OAb1rhJPA7R1cWk~H4b``~X4TM1>f0IVKtguNW zZ_e#JcO5WUwz`G{)R#FMR?b;ZcSmpnvFKEiPELHCT~0Q~i--h$Txodfxegw7$RZo| zX1sskG3UW*ZU#KPykZj*HDiBGYPGfs1qVO#X+)!t;4Ofb{?%@RLSN4nutKvdEhYyk zFYM+@NtDrZcnLk~hxuCOzbcg6610-;B)e~oz6vxw3X3FUk5&@83xANm{w^wRzjS+r z3PB^{Dnm{#Sj4tOVX8Y!PI;dlQ>=FLIu`K zyULoCN*e8LWhq4vQn_UZ!|Uk%^~F|3-?O!z;Ly+?*KTetr;QM)Xo8*_GT+Vs;hS(> zhs^er8Y0N%e2ZLcS4(*IVV(4W1$=!$Msa2+#I3J>XAq8Jn=`rdUM`C2tv}{L>j~z? zu_UT_Yyx3VF~P!Ujx=7v-8Fj;)_JAF1?_ymMdsM?MZRdzwJ-Zs+i#MY!K2_7V4qbY zEfD6mOEh4%Y42yHJw5SN^L<5cWA%vziTh$y+o);tUYS=V2ejV5ZZer{+93|OAdze( zqoC-xT{&Q`^n#%%Qtz*{&kx97oxAY4*&15HZzoyYdhx28vv^TAhNyY10zOS%SqKkh z^j6fTkCkcS1?v8ZbbM%OJKuJBUW<;2xw6M?Xm*l^L##B_myu4C%(sT>eY&Y)dn5K0 zngt^Y*Yh`8Fo=7N^));?PvNGsjeDlrK}oI45**?wcQ8zzDSZ!?EHB^UrA8a6c@-XQ zd~8~p9)yjJtzj?P=csHgX556ae2CxSAsy*}%+N@?%3Q&-P#a4s3cs^JcYnR}OT?Gx zv&?`t8P~2i7efQ7+{VX=WI0glPg$e+8NR`q1{s_8({Oly!7K62nFgwj!A$1yoyMe$ zrF$WkpSW+|7Vc+e`Yas;hjK&6hg3Xg&Q%{SxMymuw(fcJoH)o7ypgIB!yNME-;E!o za#;2ETP+xIGzu+!2~Mi_=+p@ZRMqRK*%f`j9COR@VN zc?cS5`=aQb*VYg2OaJXiu`&vOX~SvSfurP6_d|C+D>+G`tpfv z&ti*4Cm1edd$OqSnp4hmZ7uAyr4aA_-hUS!@J%7Lw%o60jp>fjRH{D6b>?&$jntjU z?;3sO;NcQ)dYYHRW+E7Pmzuw(lH8FdJ<0SIYVqjaYHFLE%=!C%) zem#mpcfM>l=VZ^?jfPKVf77AVFVoKkR;J zHS6x>-1p1yyLLiD3~HKlXuS>|9)78q_I{~?E+a?!pkvni=GjCk{A>1`=DT&9-yG3Q zuDclAwK-t5xNN8T=`#Jhp$n7PGqej`F+vJWL_V>pJJ&3=AGc6u=B6UtxzCs5AN*g4 z1R_0IETFW}^?PWao8AL#8XF@k^7J!Vy)7h1^5N3tnzs`N5<*hH5P-+Bh zVpee9-Pg|#ANZDiieW10=%c$a0{LXVr=dBAmv`6b0gg9QH{j9Ugm(@JEBum$n2qOX`qSkEL!RK*IZ5wM*=8+^eB@vdl+CVZh|#WY2_hvZWNc-^hy`}Zs*x^o{s z>K@$Myw3C&A_(kmyZ_U9#g6c|x7Ylz9M0=^jRp}`yo*akI_;jE4Bgy(gFz-F*4FCx zHOwj)wzXQzzfVKK`tOd^cD^#o%_iY72>SeqSp#OQnPnOPjCS6CLzt#@{#Nx#%K9}g zH+SM#d_Icp$>QBbebDI-%>{bWo~~GwSZ;Rcw)x5!*5Rs_tadbg0sGTGj&sh0501rzf-S5k1}p za(nA*>1QAHE2xK9I2YaWzbo^_ur}2@^J9J ziB8`q|I(L(1~F%zbkm<}ba!ow&a?=z6?=YLkZv>`&Hy_(fFGJ<^igwS2Pb#S0*scmj< z{wdQX0^bB3*--&mR+dlsV^dEIUDMMRj{B+RC}A##r#}tmK0JC-)FEL>5fMi3i*3b) zRBzl(ucsf)EbuO`bj)|wF?H9gR<*wC7LW~cMH>21ik z@#%j$sSa2->}wmY1e5pCVneT{wz2?g8A`)SQTW$j
lqpWElT7E20=@evM-Fu}hQ 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 MDyb`$JbM%PFW#mevH$=8 literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/bloom-select-the-desired-amount.png b/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/bloom-select-the-desired-amount.png new file mode 100644 index 0000000000000000000000000000000000000000..1d150b3153c7b0cd9e2468fa5bb371637406a29e GIT binary patch literal 17802 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 literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/enter-the-amount.png b/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/enter-the-amount.png new file mode 100644 index 0000000000000000000000000000000000000000..e8bce3628e1707f29b2838b64acc07a92e1addbb GIT binary patch literal 21432 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� z#=&T7;HesexE<`_TqjPf^*7g_3zGMUhO|KY4%$wpk{1jVDi164h7{MunIBHbkjYre zpe(xa&wf}&T0ukyPY0OSB8HL$B3KBo=Wo?EJ;gmo^6t}{lmB5Fe-GXS{ACuz0ep!` z-%NFrJh{ttA4)0H3O)2X<5%qy26HZYQA( zOS>^ex#SXD(fIRU%BK?88{W_rwuWtFbSEiwtZ^>Z2o%j)V*CwODpV>h8T{4W;}58AR$? z(tw^mUYURfaM(v%0`-Bdf0~VzirUDhV-{mzzp1r}ItO6PZ$77D(m#h3;#6Weku5xR z09~XciIA%MD^`lTTz{7gpFq5~80H}>@d5Q?ni)^0i2kdubY^`^ zEC_9CGPNAS@Tve7LN+!X5_mQmhAr0(@}+Y~qsXh&{2;IGF|MA46%Gy~FUqr4^06^P zv?bOq{#^eA+Lv;e=pb$+WYpK$_phI^yA7EZ`F? z8q?NW=GuV>X;4OZ9{eTA92nEBs0MrBM0l#T8R`+yW4U^~9Kzq5-&*Fj5Ktexr+}e0X z$>|AoTHe-rNLXc&8l|j^cS@z0jozIapYa#x+&xQGr!D2Seqz9_DJ5pHaj%qXn-C(; zO*j`!a1|TbDdsj7a;96?lj$WBx)Y~bHS!tZTv}BmzjdpVPl8UE6B;5!s-pb z?E$+hu9gTNQ~z@wQZe261}p2esfv!SkhXqxF?mPQVZ-1Fosd|3%~{Kj2dKeg8}E8> z2T1ki3C1a_@37|q<~DxW%PFfQWBhe`nKGv5>EVxhK8yGiMHI6IQ}F78&6OFDBhd26 zd<(Q@NLe|#noBrgv|1Mdv#s>rnrx6NwZbfmc z67HK{WTTVK9Y9iy3cEF?(y*c*3CvBJA8ZPB3~`qpCEg!ghE7x1pFEGx0ac2UVH{f0 zTzWWd^i;ILU~C|;b4!(vjd&0a7FuGz>3V*)e?hZHONNF0I0{Vy1RE~!{q{@d6DTt{ zlT<)5eD($RbB!>mE-*PMKxR{rEaDnar0r zbJY2rc%4C=yDP0*c(19uLE}Qu_YL|^g-8hS7D_9iEVKG({B<)Q<))(~+Z4GEdqQQ= zKw~k4KUG9ST8Rou2qQMpEqvjJ@l+2QDPf+$Fb|ehm{lbYzZkS4RgLFU7Hmme+5@bR zh*n3qdAy9SNqpSlqj0W*$;Ts$`MM_aNIVs+&5&o}Zt+RiqE{NIQ9HG@HOe zw)yCbv0$}P)IadEqd^i1g%V@nod1BKpn-({;yC{cq>v}$RJl0C+zlKEM5PCQHn$uY zmzH#n6aXQ{DW{FL%YkU%WZ3mJ@&UkV@d$(_8y1ZGhCPk~S0{@53&sTk156g!zxi^! zWQn8TFo|ICb0x$g$IV~|f%2p>@PG}Z8Fr=+eoDBt{DQA>2A;`_E)1v%wWi5iehkb& zAUei(eQ*HFD>#;ml>5O2ByU*>!|@0UD7EJ^-7!eytfKtFDfAi^b{BRMS49t$G{eT! PKL)5MYC>z}tziEL`wlOD literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/review-and-confirm-the-transaction.png b/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/review-and-confirm-the-transaction.png new file mode 100644 index 0000000000000000000000000000000000000000..40e020cfe6037e4e070076eda50315955fd13e2f GIT binary patch literal 30691 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 Q>Oqp1R*|ZBZ}R1T0i+$wf&c&j literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/select-send.png b/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/select-send.png new file mode 100644 index 0000000000000000000000000000000000000000..3fc42fcdce5c6d58df1d8ab71aaa9a31f29618bb GIT binary patch literal 14862 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 Iq)EX40jX56*8l(j literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/select-the-smr-token.png b/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/select-the-smr-token.png new file mode 100644 index 0000000000000000000000000000000000000000..46a1d2ed2fe76721c8c6c23c7af79f65e8f76b8a GIT binary patch literal 29704 zcmbTebyQW+7cL5@fV4EyQYzBj(jqM&-Q6JF2na|k2uK}iq`Mmgkp}5FbRP~~hj


)BzIl96h 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 literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/copy-your-address.png b/docs/site/static/img/iota-chains/evm/how-tos/get-funds/copy-your-address.png new file mode 100644 index 0000000000000000000000000000000000000000..00238e8d01cf83d3883b1f7576d1222c97c0553f GIT binary patch literal 32293 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 literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/firefly/hit-send.png b/docs/site/static/img/iota-chains/evm/how-tos/get-funds/firefly/hit-send.png new file mode 100644 index 0000000000000000000000000000000000000000..45599074cccdb5d1d5f924c1771661a6c457f6db GIT binary patch literal 37053 zcmeFZbzIcl);Bzef|4SNGzbbJ-7u6$ONvPMFbv4R&_jdLEh1eiAky944bm}mcXz%& zysqn<>pbuMJoj_n&wKxO@FUFZ-`;EQ{oQM=y=ul^NkIx1ixdk40^!O?iz|abXebcq z7WG{WpryOD(FXX_gwvLuiYN&&$F$m-^Zmy(-hyLX5#qmR- zTda>l=j}^n5WnUhi-(WfKky}(yPL9p=#moWsq}dvBQ@d{hH3xLIHkJ>^>;ZOW(0pU z2qoS1@S%~-mk9Y7=~uS5Umq|kzlcv;-P@4=I9B}WB}V|_LpANlGS~Y7KL#v5T&JKr zsiv3Yvt|0eEiwwFAXLtq{=HTUgq&`8P+n7mNp?NkH^-#0PVRl!z zr*e5`%GKl7Pqyy0*gIU4JOk}s(cRer-_&lieZ1R35FP{Vl2OL0IkZ!pR6$xLE>0iA z4$~b2(a^#iB1wM8SBVN%o07#J`_pDU&1_n3Vh?ALzG$;+p6Bh6h`N(V!p^zsICnQ+ zeM3LhQ=@&*FU>DG`>rs$niERT9K@NFGJ?`PxVtiq!IFcDEx^>?0(mO>z&mmtraXIyRd-I}`WBD4 z?2gk&Re5ob)fvdhL^YjkX68OIqw-NjZ>2MM`3RwC<|eYbV?C@R__YM!I|oyMztrXB zzz~Evi-8fs5X$0UZV50R2qY-tU}*p`gW6IXLSd#BLNwczwKUYGMnW`d-12PlmSRv7 zQ)wq_=vyZR6^N4=gx`opL>NoZ0Spi@huRuYJD9^QY`_jeG{5PBf!8<9tTfcWyV#lu z(WuKSQHvq0q10R~Tr6zN5)P*J95ljM)PmMV#$aV}$v;T|?}TVfY;7&UtgJ{Rk_E}h zg0P0Mvh(xvv$Aopa&RyMJ(z7AEo==Om@RB*Z%F(>LmX-Yu{O1|HAPrZ-_SHLMA+F1 z(a-?TssCD^xuv}PKge6y{D}g92djgDB`Z4%8>_iF>)%J%*h<&~ME+dRe>uWN1rSqK zWvC6p&Kd%hu!maM(*B)<5#%4^E$yt~zqexqVTHn>=0H~)U{>~jnNmtdUg;krZXke} znp^%J1%Ul8J#9^m{|VN=tnKE>@9q43A;9o|(EXR*f9?HuXP}q7JXjn7vAbEGjJOcZ z&HP{^1jN(`{QD)pF(;RyF&`H*gp1pdnG0gb!OUj_fiOcLJZ#1W2JBoAHom`+lCiL{ zHL!p{Z%6^eSxf;s25fAG{M_u^%pC0e9L!w&9Bj;dJVxxyY-~IRyzEAX>|BQIeGO34cU$Pc%Zz7+??#(zeyQE zz>)}Sa|7TwP0bBpP*zI|*zX57fP+PqWQ1rqSlIsAq69avH3kL<(a4!v*g5?3fr_a) z^sTMI4Vvt{Y&_gN>|7i?d>mYC{C`aJo1QAv+6Lgn8=CBFESy}whu<6v7}yK|ticVR z0t9}y1A76BSwjtM5!NaQ1YC&bh6MG^$bUSR2gJ$9z}7(Az!nM+W#ixiv$2CY_*K|> z!Q5PPB7cw`Xh`?jUE5H-Z#QSE%?WgOPksN^E>`-`a`1LLaqLI_s3hf>2Fb@ zrv5DyU<1e>Td*;(hZ_A}CqV0uM-USO3m6p89)GgyU+t#<1uFpO$8TuFXT;3O!3|;N zGBn~~<~QKwV1^hOaYFey3=9qU{($u#)NK&PwnzhOs3;7;5x@#y&)-;4KmUDD4F9?o zqzUxq6ac`O+1Q!?2^i0xfU*9$Vb&X+@z;(8S^r;{2>$NyHzfm%`=bp|UVtuS{f9FA z6Ek4F|C2v|p2h#<6x7uJndINX_djs`2d;k$fq$#>f4J*EaQ#~d{9B#>!(IQs!G-lt zcM56&SV2g@S)vhKcnLUK7>2S^;-KrBe_yN9!hx21meLx4_m53@^B)Zq8&3>0V%o~c zOJJ^`Q9R@z{l3Xb3Ib7sWW+^P9L6^$kq#>F=2~_U9IMr04{mu8y?(XAe88fU>iKge zpc;9ZZicecIsfPvApJJ>V9I%$`ydi)RVZffoR*Ck?cS%C9>@EF!k-0}BW#P$ZmIlrjvf5*z1AcZROZv?Rh7IAmZWh zHt;)OarAUsf`vrc%ggQ9Y^3s0_MZ|yv|=FVug*0ekgrHd8uOU(ZZ1~lbMlip<9YBV zku~jz9&0RX9H3wz@k5uKHn4>F)*Z2=(=YyyU)eRZl{&7(D53@2-u#6hBZb;0ty_eTom_K;! z-HTt}-k}5gQZF>c2W7_%rRpZUCzdy++?u|FO+>!2xwC7ZrqMY5kXRm$dW8Fsk~494 zU&M6$D^ZU^NVFW?`;njG;@wKGKHdUF*TOkl6`OUqO<*CHpPXig^3<8)!ErB@97RY+ zu#+K~7;K(UA%lrh z#C=lb#FQ_#hV#8|v#r^fv%xiw~#2PRe1{ zsBjWUUyV`8CYPIUW82uob{AM&SRioSVB&n7L(9vmmn29~p0=>~n9Y5RPLnrN_J&c1 zvRLqK5$~Rw$}D=Y<2LO`)ar2@xzD2jz9J20Yp@c5;cby_hui@n>t_17Ok9;1E+9HzYU!t z3wk5L0rhAAbh-}5?t|vXe9X?(9+`nQ`D?#eGALs-_~Da}O|9=NPf1W6J` zFh-`C2TFs$rRH9tQ39qU8nzBQk1zyxpHQ4tcK}>Yj8h^$h;>K*Wo`*E+ z;*IH3+dGpc{Nx$8rzZD{xh2gq9rUxJWQloj3e;$K2C_ZiII|8gSBRa~(d_DM$9gYb zQOJV{kqe>qqbcAwCGizyx@pYWpnsbXgAixjw_ca`6v{OTqRz4nM|HDr4@i&j_M^-j zj5r2LB!s41EbiO1x;K23x&97JFi1mjMK$mm-xMuG44x^f^|v^a-NRv2Gn+{cE5`JqMWI z;2pNR?Z&wKmmiaf-$wF~?Nz_dw zE0 zqhIJ0E5|383kyqHC|Z^$G0!qfb*)g=Hg5`t-$3nuOim9KV%(nPuA9jk@+yhd=KdsLk# z1`Smrmy&t)Ej~0btw6uK!%EqX-jE`9A=&cd#_g#B^A|&q69475d~PrBJhPdpYEOxE z#(C)KdgD5tERu|u65=13;MOIgdpA~+m2A;I<3{IIgH1WuQ`_5PfL>r=<{1xMEML&RD2stGY& z8`$XWsL=ZKb3!=gOHt9;Q1ABX+Qtvu5Xb#fQBZW3aY(#hK1*7i`Ux#$t3Mbd$dSj$ z%|ebUE-s#pNIT1SKUBXWK37~1^$u+PfClI~?JOz+8X9EW%*$FvjLqil9g!riN8~F= zb#dV=yJ{OR_E!?WLmGzk(2f-j_KfpJ1^Zngq2<&a!$MMkvE>%{Q%fTS()?h zy}ed_Hp>NZoX(NWvMqDsbJVM|iN_MsN}y@CJ#s+i`2_e299z+XB*VD}uUWDx?Mymq zryS!yxQ@@xZAg2+be|&(55%GE)v5^lhHwA0K;hkR*Okuz`#mpJoTh=vh@v1Sx?XL( zI;#DV{^uM)zURnquAOHoDaOi~P7%nQ&8;KBAfgAK74ecrSGLxrjb^aY^t$@yHc z-1QW1p}X9Bu`LCka0H~KUErG1Oh~i?Uc!cK$JoOTIyrZGU^^?GyXlO#-^!pWS9Mt+%-N*i!g(cxtEhhts~V?TjK| zjz3%_aQ@4t{-3h5<*ENP#{WG7{URnI_T>UrJOvxq-R2T|wvvd8{N3ZamLUR=tSV)s z&1$q_LZb^c#y|++r|?`J!m!MO^r?#{fw7_~pUnMOeR2--%-&+d;Q_qi%^$4}MdbqR z4TQr}Bp(7kLEF$MzJJOTGQXrU z*I8m^(=fZZHR^Mc@l677M~+#}2`FTrnOu{X9npd#PpmgLa0K^F5J$O`owK;}+1JGu zs%ir7QiA%~waR%t?JYakNx^spHc#7nKCodv{=Q#078&=ZO0V!68nAK=Lwflkz<77B zJ-=O?p*E=S5PmXLXeuDWC zQ4c~ieZ!WG;#qZji{zOt?aRK&Z%ut;;Lh+-zvhXNyI^x;8RIV>PohEI#ii}69?CSo zubCwvhI`0_z#Ruh7tjbapN$7>JXAGGV{1w#FXRk-TrxVUZ*o7t)b&8#{Q6sRn&WzS z(kPYd=X!kGUwDshU=S)P_6&Sy@l&e2A<=B8 zui=ww>)l6=3)g(sG?D^J3ksK8ZwT9}n_8ylW1%c~ROsT%FufzEEcQ_U)q5adPR2ev zz4nGjS`Ui=*E3AuIh<9HF1HLoIET;GOrhd%S`DmK{&bl6=4s_{5<xPji9kbYu1ochhJT8;qo~J`g}ZMw+#U5wfe`S04q7SzGUo z7VO`5t&n{4q%A4AqDW@T8Z7#Hi<$qFSdFU6IKOocj~&b%*~RF!S~7ui*1U0zf)oeG zPn?d|f`LC)fG~^4qF=k2JH(iU$O~Yh<{C$+Zk*BK)pEyE__S+ublLaD1;F2+0bCKZ zY7|k-RJlB@OSMq+MeCknE($e(>#;$ez(;ojcP_HhL@mF=HR*xaU^;~$5z?ngkp)ar$oqeKUgo7FleM^j@U}k=fGWsiu%>F73F>r~6`j2tL_6&2E(?;8d3?H_` z)?;;%V*z3JYZ*l0bm~0 zoayF5guAThhkWT%hC(&=h58VHJ7WRYhVa3|m-~{%r;EoD4~c`-w55y^GRUXcYTAkx z263iN9D=4keNW78o6OMP19#CskhP83)TuU&B&=gK3##H582}5hG~(375}sC-GevPy zhE?s)ec~9RY)>bVi?8`YuY374`nnd~DM zd4wD~+?a9?x(!#-JYicvCUzLvfRjiXLRq=uPO755THKr;DMXHA4i@NKUjjc#QM0Zazo z;&_o`(@I}{j)FAI>#aG3btOz;jhOa}l>(%H=dey6j>{fIHG5jZK^^LZ^rrz-9_Qn% z`46pA%kYh%Z71%<2KI6OK%P%gdX_rtLQXV3V}Zkjs?1)xI^PfI0FIVFT*6;%Nuhb{ z?h05WE1LL~JjFSV^MSGqX7y!f)JZCVb@XgOyitpDOD2s!brZiJOBZAKSIPO^SD7Z) z-0Xukwz@vi-^2~yzPAl?_F%arIF)4`xtO=cqRVOiMg0&kY(`c0T3eU=sIl_oNC@xMHY3kA z-%pGO<*mdnVl*O3oPJ-jqN8uWI0x@d;@9r4j)Ys%`c_Q{wp`XI1=9l3cN13TqA2_; zI{Z6|{Lkp{e`ApTBRU*b=?B=NuLFF2$;?qDU)?S(GgQ+3N=xZWN{)xO`3uM7UcV-7 z4NWp$?s3i1EdFqC(DgvaH#3ebSd%NwSeμ>Fyo<96|W_Gsv;scBO@xcgi6`Dlp& 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 literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/evm/remix-deployed.png b/docs/site/static/img/iota-chains/evm/remix-deployed.png new file mode 100644 index 0000000000000000000000000000000000000000..1c0fa30d6f88aa98c9cdc6cca0f266384ba11a65 GIT binary patch literal 58299 zcmeFZbzGCt`#(%0BA_B5AfFx#*rANbnv5oGo z0b}sYPkiHfe)|3W^ZfU{U#~lMpL6ch=epk4^*(#2tF20NndLGO5fP2L+7mq@B1$mf zdGHbi;d&vUYe7VG1?a4-tgEi9%&F_;?%?cZPei2lF4maRM8BIc%{)3PYLMiT8dWpZ zZSj|1u9^|8s$7kYBD=2fk?Qd;OGXBZ#&8=IW0f1o%i;IK0j4(stOWAzuYVPiFhIW{ z1EY*vpnLFUSbxfiPWQ7dIU=Xv8I8Msd5lCSb0p4zCRc6UTv%Qo+~C~FqPhS5b8n2g zNqPBmqMjN2_TCmn)myJI^|r%-lM6oSz>trWMA5XKJXRgOVRg(zfuuUO1&Lnf4Vr87 zM%~}J6%NUMpcrnsOV+C$tcx%(Vs## zEoxU@E?o-8`zZ-=*r;sW+1tOz>ml{iXV8-5;YZ2`qOJ3N=d7@$s|xYSa&Kb&Xu{3P z)Ofn*wQ&lX`>osxI`S*+6to4pEbOIS9OFAiTi?{kbCjk9`#(lJA7z=NyWLW;MU-(P zQ&v{pIg(}H&do$2gRY!9o%I$~`NN-?b4@GvW93CPZ}f!R++qY5t!ptg?e=Xh6~ormsxY2V(;I)qZ)6MulgJwJ2Rw*$KYEk<#^=YK9}p$V*`p^z zva58@BZ%3e6buYM^liI_AQiRgWG`V~Z$vR8IzPRn-=f8r?GUX@lDbS5)G-)ZpMA&I zUTMLJ8~E5UiDR?$|lmFORu7?vM8xuxhDFP#q){9HJ-W1H=NJaWTW5PaZZNc{Cr0= z>O_sV;<{<1n@T|xY1g#{GB0*#RnQ%}&q50{dsM%4`3gQHWk{^3eR)?gs3vxeEz%(? zX6QDUxZ#GND*uq2lb}CIbGW6d%wW8eFvSDNGY-+tlm|Q=9X4fR0@N`!m1Wn9t`z=s zDWf=+vHB%l2HLoz{d4sZDfE@hqgy&Z{EqDc8C%G#BDa6I?&=>Ko^hdH!?*`8b&#pP zq6<;JsoBNzjOzw{&n1~lVN|)ZrfYYb?p%L&`o#PzlkA85pSR|~bJypd&dJ+|mZu&k zOlaQzd__Itu7ci`cba^h3^C)MkD`*)jMY-V(YdU-IJlI!WV$%J*i`$u*t;~2MHB*_ z2jq;aj^8$q3F>-iC-2AN$LuFl9}@U(T74_aN#Bh(_{$RwT6>}F6g_1rt$J0z!jckD z=2kI#u8>}OmSstc6+Y!u`7qLet$;LEODnf0Uo&4OA3lm4trcT|hcc>ZW-$!L4Hr1w zbEb3R5L;pCXSqew(&6^$@+Y%T{4Awn-AUs~0&uD%l_dM5Ffn0gAJ@;-ZdDUz7R9D! z3}&iTAeTdzk!n@vPN!v8;URQ!kR`63R=xA-y(eL%m5PqZ{pzWm;Ey16#}U7SlY`BJ zkppeO*OFo(RY}!a186BI85Efok=AHgfi`Hq+-&R5cAC)gNnTY!2bOsL7|(i|9-4T? zmWKX{xonZcM6C5TO(-iF%cUzCSB{u1B#-U79$b0YCvIVF;^>RHBeX;^*kyz9%*n{R`jJYx7&2Gn^wpnvHeKprYF5g!6hf+%#aUbgxbXh7qiQf@*Q48ea?1<)r9UtH`TkS!kN)#(GdY=pOiMRDjuK`2u~R9MF;Y0qGEHxQWk5)nzw}BejiqE_L!Zgg z^(86ySI{V|+xFA#Ncl8*a(T+2^8?5p{1CN?3#{67YFpXN;=q|6d*W+OA;+R;qGz?o zP_hI{4^lo-c5*X{JyIx{yzOMAmq~z0=_`v@-yVm(Mpp(+h)%-WOgv0H)IH3@wbk^x zPNOI@88as{$1>%t*{w&~liI0fKhN_2aQAxlNLHI6_udbF8;76yYA$w43#VPG&uO0z z=Y>98NeF*f*fIT~CW28F@$2PH?Y@EpTzO4-jBRAcwRxL)zPYrH$oJ{jU=kr|4<1@W ze>DEg_-X$R8nY3-pf1>*)VF-v_w+HAbO2IpX&*%CTxiM!57$_zk$Q9eEt+a#G z_3YkByVAvv_dn?LqjPU1704ONRzs57tA357F}!8Oi?F5lC!C6L&6RSWMN?-BW!q<`$M3{h9Q%z9EGl4y;bv1cecqEfi$53V7A1|y ziYBV{0_=x+Itx3B3IK2uK*edPI6Wdo*jpIc6jx!?Qj;ZH&=j0H*08uPU&>U{YI)6| z-2L@#=r2~Z`+|E@1+Rxb+#v>@ovZ-72CT0ZcXI`1YuQgq%+>q=>eSwISHMy4#}}|Y zmC=9(PV%BB%lU&5`Fy1X1*ne3c*Cr*y|og#)c~Pw8nn69yg?--{k&xu|DrYU;sYr& zCFs^i*$J<3zq}>mbt}nRIUGXyDlWNWN265h(rfzb$jB$RoSk=oj{-+eR{Edrcf7at z?~G&1y=CRm)S91{Uu!x%9dsM_b3X2!AXFzp&TrFTI=^P*bM8PYm7MpUz`EOrRIB%= z<)D6!`tMD;(4l=BV4>>zEJik1W_oGTD4=^?4{yKSOS74UjI^Sv^O|$n852c3LI_z# zwxEOWtacP9uS&{*cHQM#Q=z!S)E_cI(B!za$rY^5kg2d-+vvRj&O&Uz(vDGzdMxFa%8 z_{fT-aRvmANYfB#pV57>;<~P~!3K)&oz? z$iK%g;_*STc)V3j+Y9UM2?3*{jLTd<(yXbMH64O^jwQct=(P6kcFO2JnV}7Cx}etZ zjVd?(p79%nytg+|chJ%z;v+m?A|fMZAtEO{5fe^%V%Gn7eoB0wi1Z)tNr;HToQcT( z6-S$J|9wOe&fjVNc_)nyC88w!x=uKKGf4g&n-ZKs`tN6=K|&bOV|`_Hb;4cW*2~@= z^F0zH0z zhe*~}n(zp;2U~Oc0^LB~(!O%H{}Dr)@cjF=@NLe2L;<_X-8RwEqne$iKhy#GbHBIeUPe-9encziVyd4gt&EzWqC+|2Y0xPJ3VH|I7*G z{jX{fDk%IrMEIf51L6PpHX*6(@3+#r&c60;rca!Kgf=7OAusaak?cR>|9?XMGspju z(&Rr=K9u_JN&idG|2wInx4oCLJCKkkSpGlz>tFf)*T8=zlokG6_5aco|7_=fyd^ZW z{AF3;|L8RN%ZZwRNK<$McZGoE#h)DjlRyEuj}-jid&G6FS|;O_gc20I)ALe-OqX74)0A~ z<_;L&2oopxPRCT-EzbB3m!KlP_>`C|o9xrDx1mHNmpEVk z_2SV-wZJ(jw}hq_x|;t`@w-m#vkT zoYJJ97O<6nUjey07PQ!7_zj4pjh2CKy`)aZ?>|d?;2HS6#=}UcY@Z&I;P%xRLQInOhXe#=S?10CC+uwTIwg24I5&VRrUqP2x zHlI#>_uNWJw?E6Z6@4Uq2znJe%G1DYTw<~JoiuVn6>x#uZne*)YOdBw-D~bk#8mhbmXc2D3jAY^% z>d7TIPNgG)EwybZA1W!DX&B2lX74@B!z_3DdX(~vp!MhL8A^j!?5yyk`T7g%rT6R` z$wEL&>Z!3ZcczH3Ct5;Z_LIb_byPFfM@L|N8X3JO$*U-=$TnAZPk4GGg-6!r+ zfsdqPE6EyGTkmBaIdBisK;)5snFTY)H^T1^j?Lui{pyJ}X(;+~-&F5t3oV!|;a;U& zy@hF2_@-9x#qe!V{a$yCLT%6K;rd-39;1R3Jr$QxS$H2E^Bq^jIhR7RlmQ*PY{FU~ zO&XtJfq;EaT+Bqm%@bQVM+Lb1_GC*?K!GhPw8?K@p(c!@bb z?5tcv0ywooyU+gN2CvOhli+f(6=YG|2i*g4MRZj$EBGTJk86Q+*Pa;V=??YvCh^Zq z1O*%=ECcAv1V=Txqp9@DZMXwyD7ETxN}n$qpvvzYxE7gZCoPD150+Tf_FMF(kLUPT zC+Sr=J#PeV2`luL02-C#41XejG#drYNmsA;@a7s+BOW;Pg?UY!El(|dV&!)3b*N=I zvb`Hpf_AL;T8t|;uhodoFQEnbZo`Tf&G$r80h?re8JA!$_eSbCAF!%y{X~AZUbcPb6nNgPrN*)EuCNX zMbH?%H9VlXGhL@8?8NhF0BD0bKZcAZ7TlKkmKq%{hc#R9>ZA$PdGbjd|SGxN_o!)-D zZxt<3yVG?ih}*G0rNU{5gx-WHR`1bDK zmzgbY_FRnwuv~yu+tHnT3#TL9s$V9?ou$K$@@WL|Ox}Cl44WRqr?10wwMa{?m*l8G z&g2bmFEd0V-M2wYr2URMp8Lq9?if}7qrlPN;DgRV?c*U6=wjIUDiHDZA_!Y8Ai)sXre&37#O^xs-s-UH z{$TTIfsfw)sM*o2Vr_Jtb@R`g$z=NFg>B(A1J8VqW2iLG;N&8p)(3UIN^F@cMmvbf4SgQ=}E zlFa)^-|F!(R34jg8TqpAH*KNwF+Tw%plr#!pj{p5x4$Hs>EYfe z+xaFmJy_ak+7aBE?*QA&Zz1l)8J~rK^oAX9$}}_{&~5GfOTxMt8O>12E4~&7`y(|# zN?w;&wm_9<8;ALTB&DxmeO;Fog6%ZbV zf$?L4E~?EL*g6RFLbT~YT?2E!{%b`bOA9RwE693l#h;j-6XUlmCvkK5>cMJmdYLkE zO&%!t>_Ku9zo`Q}iTy!eQD|FgNvleaao&qa*1f$9v9MzZ7qZE(wQHh0YjfB1WL|0U zfCNzdePd{z3t3E2QJOFarnUT+0)!=1lRYT?>r`L`FsbX zC4Qs)oG4R2x4)*8SHDH)Fi{2-7$?+R^a*v*eb06w-fC&W9=qIkO0y6h7e6%yg*&?b zdT;O5_7=V{?VU6MR1R&r>DA?oTBQR+0AY^o;x2EnrX$~v=02FeGrB=ZmwB!O&s?Vi zi#{11#7aW6eiLTX@dz61c9K$!dyfTnY zC)_-jq&j_$;fR>UuzXDJq+cG}xuS8{H8yuXk`Y%q|AQ*SPtsQkDQepGVW*_LY@r6E zZ~Cgp^!dqHpf}ZeS1rU~_;+!#w={K=LoL;zgzmE%M_yOowiiXq4!GZ9a85gsQ zb-L<}EpZxf>)9T4{br4f+XKd1JLKuOnb*zAMm6i6fJU@E>0=rL$W7aeowPUx%sF$xHa+F_*x~%^XW_%F5<6>D6xwbV1`A*PSOGEM8notT#elgZ)MM z<|go3?fjca&|=n+-wRMjqC-e{zAW341Sh z&3+jQYvxk3we{9$zO&ySS`a=OEdKJoeofQQ#Mxl#8v=Ie8vGw2v}(XM!yi8LpB04c zJ~(6`%jZAoDUt{iZveOkCSJo{Ef=w1JYh0)RUt0(GKE+ z@E)w{Q$zu1Emu$!;X=1S_ZKMtjW=ph5nkUpriluWog;9g6hmH6tMqJPN z>JB2jabgF-`#vRa%k=kO1!+qqw-p-ZRc?)0McwSdqQuj2FE(|e?-zB&ivjKX$5On|$N zsGWNc9p!(vUte$eI7Mji90;A5h&&VXJz#0`QH9%d9a?BzwyWNIxu%yHKg4lGcK2r%+IlvS zhczAfB*}8H?`XG!Rrv|24{RSsX~%OH?vjxlyB*o_X&^pFOSmGQsleY97M`JSon(6L`YlfM$`!&w?U#VNbB^cb+ zy0cQEtWRtI>w3^8M}?@=B!vr0(^w%i2PFwvyK!>5u5PJtPR>-JB030ZZ^>bb#;%Hf zw;bPF?6vzDUfZMzp8X6f(XJI`2?5gyWIN_mt$3w9=3rLK7zI`WDKFjm^U)F+BEK4E`F6O|->&S}Nc5X}L#@0*t;oqn_jH82MfoG)!84aVroH(pj;0_`8^_AgCeEXv#|vta*9nsz z)LO4x{kq3>xF7Vg-9rc!RpchLAV>#Q01TDAe9Q6uE+x1K> zX-rX)AH#8u#b?K-QTtgrESjO#=db-mBq&kaNewoyZ{fZrFgKVee+(hjFDO%jviTQM zgGVkWo;fZKSShmm&R93DBCM9W>U27ep}CEL(H0L6T_o*=$Mz~^aFrH$#Vln$@RT&Q7EWJ7K>^KFz{(|E#%St$*r4Q+T zNqfxD^Gu*(xI2r;8m7vr>tBWG_phiUp)2tz^-{7&p&71>L zRB(=lh>?+iYyDhWbJ_tz;lZr{sRBG^D05rZwsANN~!WkNTt8 z&rq+M)SoR1FIFQC6|tFVks4`De)eMp1ocWr86Phs?vla>MEaB=hpEA&+9Ld?>}vt} zf}^teTb5QeZuw1Ew9HXmVX4bKah+oOc+u16uUUCa!i>-kp}r+X&7sW~lvh^nusEHX zJJU0+H|J{=VlIyF9NuakD@1$=JlUI+2m6AHg^p^~NKialLRay*S~%Jk`HTH06@i_b zsNV)lq)OgE9H!Q)6^-_o05nYVQc=A-5??=bzLY-6NEqW`wd31HKzg2t_(_FtOWz}mT6(OwYO984l+GR65Mzzh`-!=Udkb|M08g4LRqrKQ_)DPCRr4xglF${yu z^Hi~uU|jI2b57vVq;GA~l5J;%WMX{}e*li4BD(}X+D)nLC;4;7brvYbk)kMQSTsH` z^2V07_9yetcLd+qt6tUZG;_W=UBR-_@LqTGUU8-x#EJlONtBpqrp0_mB%B6E9MmQ^ zeJ1g%XnZiQ-nTq}76Ba9t5?stwVxjDowDW^-T=UyXf4%2z(={SNi4I7c z3)R?D(RuQn=lWfk{&BVbw4B}92K^d4M%a3BeLw1Gi4jM?jL zf2`c#Vf$eownqy(m-2<69a38-F}JC}I;8=j7XGHJNI;&S34VaSyFy`*ro>=;`%1B1 zKLMm}NVaP!oETVb=LU8yCBiK3mtJk9D*BJIX&@RN+c%6G=q-aHx-Iq1=%@-p=i%Y_POfM z98LV1aY9GqBW50mjiZ5wS&V^etkvIvbiqw0JfZ^i`3X=#(X1zRwti3kY|+I0)_M!M z!YQ5+RPqW$u`&@1RFFl>F6)HQjC)qr{!<9haChuMr@x{RDPU7a831Hy2y_Z<1(eS@ z9e=|O$du+A6q_lh`LB7F4(qhvq_M9O{EYxvv7g!IjM^`;br|u_S!fCmHWzD3^2X}+ zuooy#x@3d$GNuk0&Jq$|aC39|jT(`-a?jwl>6mEds>Iz!O~gz_a=i1_Qew}Setgnp z_&JoIEJ^5OD=eXtPf5j6ISjY20YCNOJcmAGl@YH=QBP?GVjFmhQcmYDo-708!7EYh zJiEKx@W8>;<`)v9(^&*eEoZ#FE3_m(I*=CJZ|Q6OqF^@Zuukc%c15}tz(=d_Lv_!i zIusP6d?Z?gHE#`$d~>U3@?w&j;fm_@l~evVG0_sedC#{eaWed|Wo@OrqYVm!V<&Gh z%;!1y$8Y*GQJMHdy^}8mM^)~vscyk)yUmEV6sxDUw0P_HmLmu=W`&>vCJROZ6I~Vw zHvz{K&zz5v)^o2;RF@}du!O~QwgZcS-8t1srr2ir-WX@3wsy2`>(Bx{sPibThOGBC zOLZYit?tct!ramO1AyKjJq3^?2C9k6ep@;lo+$8kvDm#`8irNWPj_UOoqAJ3@3g^v11W`W)d z;k&Yj(@+c>55F-*sP`;|2%7$F`PD4~!d)|=1JgeXFXbw5^&fD)l((IW4)BLLQ`3Tl z>&g;S0<`HHbuP$YLSW>YVd26i6g~LsWt>q)A>|2wR*Zyu99QX;%a0Jn$FP@IEg)+V zyOell!?Z>}A91yDu6KCBXhmb(kW>*wXnn?K<~#9__1DU*6H)*oJ($kPumtC}7C18? zFY_Ju{Jo6!GWYlk3|nq`8z~N}*>6$bJdn*^=pC@`F;VgsmpB?#=^EeI+;W&kFXc9F z3qTw_G*DyN!fOA}S3Q=Qj*{SmCQyquQkp%34!{j--YOkojE8VPy+g zlQjCaxh=D~ni;ZYO zEOi7gml98sl>4E~uWB{<7#8r_;CJc1Mpu7K;MuNI{czt&@vK)~l-Tq?%%2Jh(pAm< z+l9SrHj4Gs1mjME-*ojG})3?p^GgH)O0nTT|8M5>R(YSmqWQU4UA@A2|Eas$ z&NImMj>nra;4cM+1xV5KfGu@(ZEf1Dc>3iV#+mEEieF>v8TgH&EpmSNFTP*&Nto$t zGAoW2jE%a_4G$<#C>tb#?k{Pful6Ob-r?_D3CeoBYP2uwia5Jgz1-a+o(*+tIXh_@ zc$%s7wr>zaH`xxkzf`}ZdPVHdZoaFRtT^WsCC_q~o{?Sc(k7-E-fFJREuNcxQBZFM z1A6%Qz$}g!ZmqD#3(q}jbb=k?T}zwYo-&%iQkqGGnEt5NhuCVqRK!mBE7Y-&Rou;B zSdpd!o_H}VoaHe2E6c%l+B{4f!0K_Q(%0yC20!&T7GP09*u&_PeORn%r9&41QS{v! zDc5WCVRIf^yF64sTKg|NCe5T+`sbN{7Djdne4*?vA$<6geo!g^nJ8t62TpElE;M7q zaFTe(cq(w#{&?rlg(y{y&2)!l>GZ8K>r#ro`jn-%jlcNHL%`&hz$1&+_eeTxUQ#q5 zsv7$(7fJx#6;87xCubk1I*(K?UK>L-mrJ6ZmZs4S_8*#L-?$8Id_`PFMXAXJ7X=c{iUJ) zF(N|3e;1tR8|k0R_pjVIr3nm#Ad z`Z)alQSI~p`l?IRMzaFyv)4sIwqy5b=`9(^^y#!hAiV&Kta?Ub`?>sNfCD=uy z6HK07zkc1Gz$U1$#!H*ld%bnTv=oe0^08x1=oNI z1Zz)`WwRN9Lbw9#jd&ZQ&F4mQT{AXr+Hb#$NA%-P17!VU8--Nhu}48}SE@|p7a@R| zjg8GhY3q5M!np}|!{!bBS&N}7ra?2Mt#*e6u@%0%KMa-~u%Sg0lnPKEiiUUZvNzX- zjlL!1PXUCf8P9lrv&(c6U7FQC-_|R!AP?BS!Dpf?0Yp1(Ad&(c>;2O8k*<_&*k9=| zPz(?mfmZMr9CIE0GF|V5#J-626IN=DJlSW8(sxbcQGqXidufVp+0+TZxQ^{QSGyns zUJ!7B9-tB#CF-cn>nb01TI#!dJ*Oh5(QUd6E${f-4ks;h@e_Iy>L z)(hHF^67Z`*I^eTKxHRA2!z5Rdd2>q3{o!+MxLE)RPO5K>2j?O&1V|mAnlInL3|2$ zv34XPOI64FOdZ`|zJkPl7E|View1H(05`6wf4a8-U&m|+UYz#cN^~k&6{h!cSsz<} z$QtZVnLtj1JUBVaOr{t{HDb0E`h*73@G;L49te#cc}O^AAadYidi7qhQMubwu>x7D zkyRnZ7eviM&GHBWCro86-LGb$C$<+@5osPBZMRZpY>#OPB1Traau*(*HuslGA^{a9O-OZgkSWImZBIp-`ajyTs z;mg;QbW;NnXu8u=1$JB}G)?G+kj0Y*aJ~LPCr##5uy^Yf7&M_sQsMnhZGoYy8tw?; zmwYZpd@wGk?$yI<*bHpQNY8pluW$`tH27x>@>>seE*0g1< zmDagZaLUo^+Targ<8J5N@!fui%)u!whrC@W3YhH9XV{tWLZs3B(UCt*JYeeST3Yba z9AU?U6*{}wA1C<{P=ehu4E>sAv>}I`VE0oz+Ct4sOsWRy5E#{u2TUT7ZhSxJSQ>xa zOTDo}N=l=Q&nyf522BnyZ`Wm-CUmZ`Lw^d7R+7cl9a)h5`gpO3?~XUf&?VJKb;@FL zykwn@#;DlLT6s2_D*M})ljS5!V}b#>&TzZj??arI&+Dh?2BDSmE&0Q3lS+r`E38Ki zu$U@|?Zpwitc03vh4c|2~m=)vYvhi&|J#kiZ}J z2;2Fyk@vTVyqc*P@jiAfjNMk^NvHI*d#PoRn{S@A-o<%j_T?AV*LTta^a_}B2acb& zq#T%rr$vAYjEY06T;uhK6P^?N>QiX{b+#irn#iXgea(%EOqL)yA;`m2&=E<6RdDK^ z^pC8zSSuJ_i$LhLr$5+?B|v?@<)1$n9xx>QA_=t`=gQ>pUwIhNr^;htarL&vfppix ztEv1Ch0iP-?8-l$94im$_ErCO740tx0?Bh*T8u6I)T5&%>QOZ!`?Fz@M(+J0h66Dz z2~Ntc#R*MQWQ#19*Xtt{&dZ>dJ_1i{N|z`ShqTeobQYj zXXprc4Sh$j$X}j>qM2QSs-&9?dwahX)W=r^UEn2;(pz5>Y^Crk`W9%AnSJQu`HO{c zq5!rnlfstj)n+_Fjp(5jP4V;?;SeXdYvy0Vsh0*~R!3l8;OfcQKAR1CBL>64I23}| zaJ+;M&^}Edp}6w90PfvO=Bkt-aLh4Q#Z{Y#(pscFM{gXzup|bY3>e4ygq~Og?ZfS4 zM(aZ-A${JK!+Uz$DY_vgw3_IG!^QEy(0U{6)PbctrX|aOK%Y)i2s|D%VCZR3hP}yD zR&gB}7!1GWKIvi^BrFUX>Y-&S##L>rTjg9NBIf^MW&SO(6Y0D3G713_jd^dy+`e3Q zTGj1si!B6BRmGZBuTAJae?9Us^c=2{v0hr0y4UIsbYeUc5ua(eIJcCzwNIIRe!2Vc z>oke|pqw`lXkw3Mv0jS8g)y@zk9~rf zWjkHs=h7MD3KafLD68%7lRH})G;W@+(iP8K$(}KTU_9mD~D*EyBV{Yc3ZS-6wm?F_au?R7%wi#)W|Z%?Au+fCg}7p)_WH zLj~UYAMZRx z$z$Kco@ANQjfb&)EOpSe(Mk5bY${vv6oOw+5xdAG98SBrY4#MGEfb;ocR^b8n^G|L zz9mhLquTJBbo{EOFdLhZQTr$*#|AJg1in$$YDxtb?;G7wOE$8m2(#H*T;CZqD=yp| zGq#G>a&Q8$X`2opPBbAP{nUAbu$X3CS4urg|KU0|ulP~R(Ui7N#Na1ZL@&V@y3z1y zWr!oZ+3CkP5Luf&nO?XwYVAqzOwY3|)Ae@*i97|Dynq$zp4-*Wc9?JESo2)6v?ZC{ zaQQreE9H_Q0nm7fm(hYiX|rR6#@$Hw*4a&vUGPhf&nH~3YG_y`yS|F?l|W3ELTLud zJITXVeX>sG3Di|9w77SFiP%_6qVrbTu&wwgs?0id&gCdExw-g zOj&Y$x{u(?U-0pZ+&Uj~9aogCLwTw~-$e>rTZIKL{SWhE@(zK&WSnlqPh5Rl7a7GR z?B7m;TQ-5;ud2G2tdK|p#xo>rP4~$L|I-lsPR=0Ab=>6%&7ma>ShjMOdoHD``pI91 zQP|QcEOtEegZRYoOMaQ8LbCB4fzey}=gT``FzK@r+V(;?$BGL>F3i#fwau|5Eklah zC_}7|#Ic2x1YGF(%bp?(ua%y(_i^FIhotO~iCk|B4U2;hzCRPlW?*Sll=NNM`q(g< zSb3nxFjgw=0lM z+Hssl7zu(ysxIz%2J6`!T4);Uumw!^amKoV@1LE)1jXPs(V7sb;*aQ$S_)tiv2e(L`!^r1JZ?=7J;7p z=H&Tfb$~{nO2fA-dd?m-zC%hUYwPL~z9ZWI_AE@oj3m)M>#2Ht4r4!YS-!xi#Kj zv~%;x5T64AthQzjs&6+Mr(cm~VE>!-IK)<&vq;fc7{8PZim6!aNnRULb}*Ug+-Rx? zMNC+?Th?ZR94u`d2ww6+0>4}0!MQgweJ?suS-emyY;oaE)_VvXHEZ`U*Nh?yn3@}e+4eA<)okpz~ukPt~hSPIkdPx zMzWMG$#|K|2hLG+9>dUZdiHs$5s|Uazb@N51zxda`yp8ghi4{_T?VkdYV_NWJ90j= zc6LZdz%1%QKm_J#_Ky17krZsbUnL_NKbt;an%)TA4wg8B_sQim)NWB;*=h(l9Of`v z_*^9~`S4-+lGN#xN1`Gk|1a)kg646HmBgB|!Ja_;|1D!%-VZ3?3|J(jjo&9oIghYJ zixaT(X8gO|1h5yIu^=_w%qj~7l~k*#-c z+I>$07kh?kbx)_!cTBvj6$F?ZD=^A;P`2IFd0oGp&T-SLWz+#Kw7cXv#uY1G2ie42 z0avzLT6Ge33o)?inIU&(m6iJ+o9BQ{rQDtpkGq(`s3ix-TqcA7TUCHnyp-?GKG)_U zQM05A0kRGKAdjxHue?~@^r{Ofp*DnUIi$8r)vd}EwiTma|K3NX9M-bLHdm|Tdeei( zO}P2MD`3-mxu5oC(j@s0^V&661?lDLfLFbxbsB4<@~D#Q|2G4Qu#HC8YWZk1^L@33 zq=ZCA%kAR8vCHjMNk-j_0tSOfK>aZ9@K+W7#u9ILc3Cj^(KG?vCC@-2p>70NSC2nx zbX&Q~SO%I%*1RGDc|{Z<3(Hv(_L2e9nNCJFjTvk!TF1n4D8qUo1L(zX>N!A^4sjISvZ zke?vUZM-|WPL=^Lwo6GVk9t|%TjqR_oq+B}J4{P6F><=6olXIiu8N3H@Js3p66v_r zIIuOotbm=~&-NrR?NO*0pI>J~92(O>*q|f1ao|4F8P5f7i*>R>T>UbmzX(V>Zlc;?g;-9gu|Le?)SU8;GmSh@$JcJayM~}e-OfF zqME=CPP)3aaMNo4GFr6VLn{jyJHjAC}m-Oux??%yb#f4Rn z^-Om0uHd6d;_)9=zcv+oe!S7KJK8Yy3AVThT8TITpP3|zVjUX`GP78mJ+{ouu%AE| zc4wVmXLD-$QybM1MHZ)>o#og3bYyq)PD0v;IJoOx<3mc2Im&_S0VWxW#I?NewauyO zwf9ED6qtGRJ5@#kis&UMD9jJOK#E8D9w3ZsXyixD5$m)ql;X$uxqT`hA;;7ask)%U zvAZX`oxFP0E;P=V^M)DJ-eP=uFJT*+KG2c$ujVnuaWX;=9OnBUtnj|QoNAYDSoqX& z;G7rEKj?x6p|;=;zId@YJvizU#W!m_t(ALNUR4D|av8qN$BCy5zaL;04gQj?8DFPQ z!Va)6r!75O&=1;_F9!eKCK3QNBbHjq`b@lRhj>rnWyX-t5KGv{nBM@X_Im3C0eX3P zeQ%-NERE+gEF^bBR`XB3Nz<7Eo?H8&9{=9=wQO~B#i(-epgG&Ea}yT!GOFVhMU{@+*nkCeO%Xx9Wu{fK9gz3J zD9nsq=ID-$n_ph;eHT6mvU=Nz-}*Jyb#bH0S%2ipbMcSvQ&pxfYmdr(P-e_PzF(~3 z(#HJ+g#ocyiwWk|&k1zoi;Fb+)tKs1XkALHX-TlE=}QG^eqSHL)8C7zwQiIN`yW*6 z9WpP2A_Il&Ch?|yV4hjll5+);EQ-KLWOWdpP0dkm3Te4uS@0wN{$PwB`xuE#>yPE9v$;e*rWHFpzX=1;<& zM;Li;9}Z)fkk~rkz@{7gW_`2_&G4op!oE<^paEyjlss%Rl{s`{S|}M_PuMgudLTEV zC|_dYIqCGuJ5|Aq-`n}m)Pmn|ud_t)XUJALZn#e5{{%qj3$we4h=>_~{};f23!gbA z_}JxIFbXB?|8_n9$ycQPg5c(+KZY-6bNvsd`tQ4fiWvcctuPC@zfLKF>X7oC;AOwJ zliaJR{C7J&QOLYGfwyrSd{O8B-)iuGNcJd%;N;htk^Fzyd#j+h`lnqq2_D=hxI=IY z?(QCfJ0S#j9|8>SPC}4DLJ02e?iw5hcX#Kk_xrwc>QtSov;Xhyu6;E(vu5fi-K)Ew zr=Lzu{a>mQ^wqV$0BRgBFI}wDfN;Wpt0f#7BBkL;;71KarlR-_FRldQ zFduzAoRd~%($38IjHrdiz=$ZOg@=VDub?73I^SkQ{^9a^)OKa#`1gHl)Aysjy*;m~ zsVT#)FeI; z2mXsE{`u{Byw||r?FCJI{g;224Jobt&)4iK9Mq&5!6jJVAjeoN#z{4npc5we{ zH?ol}G~tuRM}A?-6y^WNd-&hGjnlY*_%F`vpSAV>LS}%bE0afQEB?C!2X?;({Xae8 z|G5lt%GhcWyy+sKl9YdW+6ud0iT~Aod@W6pPL&O@=ka6LWBHG7@qeFo()eGV|NQ#? z*Ehv@fTLcvy*H`W`S#)IC}rrj7#O{_{Hj>=LC!?M+Zd!#opxPdZgNALTG`<1?Q>G=aVO* z^4ULb-dKlQ{Xh1g6ipPbIP0YPG#QNd-p=PM=*7}t%~jds+dV#0)4G{=tD!7|0w!($ zb60|d7(k`Gs0pS1L7EnM@Np`z{hD9X`k*>%Qp4SzNeg9p>00Uv{Qv7M0)nst9`7!u z01yeYQ*c&a`=29TT@}mL8bjqDcAf~@_>7s*wAAE>T0;J`FYa77u>1?BabPXAWR%sQ z9yyuGSfonD=Vo%!Qqh{tVIx_{>s+lTBDqkkkQsI(e6F=b=ntAM3gD zf-gWnuY2Wj!K(ne==AT;#S%RVmoR@@hH49xXky+J0_I0vg#11usjIJl_c|jH)1F;s zU|iJVeqW;Dqof{He$W5#Yupu%C zm~TT{Z`Y@6ms5X^mk8eYZ&9txk=gf|w>|~}>||UHV{KAq!$xMH!+0hNzjFVFcSbi> z{q_&yLZ$DOD+BM|6@A$qFKC7}x~yWg*T3=)2UU{Q>m4NH2i#({Khp6Mv&;Nwv$PVH z@>S({YN#5T6Mpj8_YaN`vTArdw;ApLHeqrjR&+Cq1EDZ}!B)TxBW=grz8U;7W4~8xU~4T$i?u+<0B8Er930);31FQ;&;y8sJkcticZt= zs>nox`{sTmP`;z^aj>h~EbefwA(5_Jz5RSkF{m<+Mp#2IQ`m~2^>?#cz*e7;qHbZVL53*LMKkHr8aZ>M0Y6X&D@7uKw z?6T>)lkd~@PKoV8X`WAy7m)T1q=x{oRi>od!3X4^*K?Sp_jzYgb(rgW%qKPcuwL02H0$7rbj~u-(Ja8^&GfvCYQ86Ty@sMy}JLVQPyN zzv73Wx7xSfx#xy;LY_N9k5LDI*i1fUUX(63?Z(3Vt%CcFU8mJ$r`Fss3Yv@au*C5~ z07RKxpMeqRpJMKuBav~5tFf6)N85B$q* zv0h$t|L+CfeQ;kI%=h7=UKzgP+Q&ay`7UEE-?U40#LL>woS6$qs=X=~tA+-V)cXYe_iL8Avq(tE?iULZyuGE|3&&F2JQN7tVfI`?Axe= z9rrp+713vSG24Z}58~%GtZwXgMJu_xxL1j}5y@0qKNI(y@Y!MQ=jkJ=DlXN_t^Cn~ z+ir2y{X?zSW~lwUr=?6`B;#%YTGuB%rBPK)3Eo<(G;N8SxJl{XkMSRVD|P+R%F&(= zlTwv)o6mLXdPLI`G=FEQWF#e+b}9_&(KcDUc>yrZaw_lU45_OF-n>@7G4=>?{y1c4 zq)S<2!hkx;GIQ`5kDzLvUWLc8JpC2g+0xKgiJL*DvfT46CY`Xmlh5q(JV`AmQ?`ktU3aIF;wvU^bhK%CzD_5p2wz3T4F#YD5(;#(bx~VQ|GueO zq881QXgEZ|+e|g`&TnACvJV@L6ZQYKhS-l*O&|B?bV;eMT@Im_k!k{Y`Iqt!%`8n7 zu6d4*fWJ)4b(lrE>E4%z%0R0ncb}23)0c&4#k^5|YaiP_6<32k)?b5ZI?uf`$H_%n z(9g>HY22bXsASWG72=xB=OX&$V~;k7J^^*+n2%3me7}EY*y3FtH#tnUy*%TlAS5mW zH*vgr1Ybmvb<^^IkHgz5NS?fnv-7R8xkQ(Y@@}=}*k$SI2rnBCFU&b$9lkoQu)N8-tspB#-4INpgT=J}|2&M~e z3V)sY9KTD-jLd7$iW*`Ufs?=DZu0>}Zt_# zE5AVC;=5w-6e7K`I$af<^75JgV+)GIAabpn@XC2f?}qt-o&oz^@l?vG1js{(BN^$f z6XPBu*Y1G4_4v#*CjCxX>im z?PkTLIE@vrlL;j1#3ll@TJ+)mEI~20M%rM5BDIXc+Y3!Lm@K5cp(#-rJw{D?=pTu_ zx8Poe=yq1)E1fnFaqZ7rZdR^oEwR2H9yi@2a)#qHI`8E3DQy8VN>rj%AE1#6DQw2^ zrOoGhWv#l(yJn6ks`AJ}PJQ4fTD!%H=pVc`)}79t_!}937KSLxLFqEU`pMiPoWTkS zOPxF?wn z)7{Znrru8v?Q< zGVqi6_#)daHo_Q&F}et>*ONzm29GVf;E)euOzqSlg}AYEnJp^N6qXq7zo8y+q_spc zl*_97J=#OGdydy6?Vc7ui<(l}!wqRDxzTJ=5Cavch{E=7IQ{iy^B?hUHWLJSr|Vmm z4)gc~T7@4x6mxeq!aAbV-DDCO(PU2*7FV@7!+lRn{x60`_W=vmE6ubS!*40$0TR=M zC*{z|QoUOiSCsSiXu93PD`adP(B?$cS+WgefK)kTxm~ zFApn;UOuaJ?l?+(LQDO&OlTbQ%h>;pzsPjB@?eWwSSsZ;?wZ8BCsD2l47m}XlNRCG4MyI%N=v5w`Ks8vyStq%qE0f=)ek6e9^cu14HdqQhuF8i zyO>nk*v6(diX6%oisw&RY8rJw2=A^PFp0fJSQfG%JD8F=oGLJV_WAp_nFN(h6~3hl z4s)sJBH2-rX?JF!Mlc0XzK|J836^1O-bz^%Hiv|g1y($QTY{I~N4XJke^F|CreO_FfxYO#fMCZ0-v`S}Hd{uFaRf(f>MT1`Q`otALb4ACPhHxVGTd1^!*;K*ORUe<;N1e~#Nte@gPc+** z;1RIOAB<71NvW~Q{RlKbLe4~wA}p_k$0Ixyl3x7YV`NZK z3>SIMs9kJ37?@A9Z@qyNJ}#|as0QT>jVbN4folC)7GjqKN$PYW)TCNeaN#SjXEpsI zM?;}gdK^d!i_-*ID0s@zh@5qIA;Pj1$=r2V1YRB^Te{{0#)Wr&K5G?>V*gU9P%)S| zp@gsR?~P6u(!jCX9GA2?M$Py>2Kj8 zfz;)UYh#uBJGgn2`M%;_Xzw`|=|;0anPZbL=`{4>X>-k+`PKuxz|yzu6LC#^BlKll zI3y`u)StEGYQ~1LV9D{RL@UQa-l)zJRrtIgjlWEl}EC+mjAeM7N;^25{ydqv&IBTZXz!P(l>r+Ui9y^vL&P1dq8=F5;10 zIKJUXd}5{A^MB;{-o@chGqC+I1?_U0Zhdmf#6idm(4iO7ZaADQiYjobR{L^`k+epO zcS;)YTI@YpY&)(CcC6^>p(br1h3m#%md3{utt8ybpZSN1bBn|qZ*E9K*5ANB_g|9= zN~B=7>mWRp_?|3nXw=$rsC=-IN@Y=$_VO3@NniI4qY5mq-c8M}KEoB2ARNp2`gecj z$|>_{+36s3gPm2U*|S1cyXzYQjQE`cC1wt4J&Y)C@nruEU6;*y9WhS$v}>OWh@8cs z-d`y6`CW)m=-)qfoj=W6oZD=y2sO&#iM^K`yGpiO&wx;RyXdp%f@qX((FG3fEz_sc zHzhlFuUZfMFL)83L}uu_bexdtI7DB^+{Ucwe*CQ#&#};d6x` zU<(n_ykyfs1tvZ`L_1Ef%e0h}nl8h}uXMy8v~pN~UMORdsQ47`!tE!nIZkSO$g&zXc%xi6#sW=aSZ+gRemjAP zx2HJ;UV*|)kLxpMBVLYXjhoN1{bFF?W^d#N(xIP4&j;^kIKUk(@-QN0%yQ#c_2BHp zxE{Cj<^h~!@L_3wZ| zY+ADD%W#&g=<{WZI_JY*ltf$*YFIlbR;E?0bDts8=0Sz|9B5sZpVrm})6?lx47<_u znLf++Et8nykL%Z!TJWZyxVA)d`NVdY0KSMn?vhX3#W==d&4Cy|pGCDfX}b^nnMhmq|p$r<2{k{Vmvbz#{AKQ%Ju6uvlv?@#d zX~Knlks`nEyBKX6H((^9WV`AhIH5%Ip@_$0*CD^UoOW-JtW zZ|qpep-?>rw-z;iuXfzYR4)=c0(~se+;Nm-FdYskcPM4nImJ}A9D8t$EYTqyIQSb7 z7fpwZzZ|;r4kX$T`0#q*oB7nsPZ@IXWoCL0DEa#EZ{LltMXv`!gq{g~AUNN+&1JIy zFxV=^5Ve)1CVN(uf+o&_g8b;9IxPFQd_`dfrKw$UXiHQNlI#@7|EpDTIwe{f``CZ>&g;XYKuRevdID;e# zvtOz4!_uI|ATP`e+~_a#ezupl7*HqpY_L1)kbPugcMStSNUNOH2F;0$@;LXr#=^E7 zOfrQVjO^?UA4+A(B{cRP6@)E!@M)(s+yx3xgSX-;2O^&A+=e9jAA}!`vSVEk#tu4= zPA-tSq;z+C%suLa=XTZ>qiafY<7ModBJrH>epZbY2s}{v_t)g9w(}l;<*~2naqtb> zNPD^2o#=}sFv|+^yX?z4{c)_rNcCegufnI=2SwnxwXJ{W24h3G`r-9^OuyybiQHk; z=1&7rEz6e7n?#!jNPo{=gVxn$ zFfpPm69~jZK4ofQH3kpj=Z2(`OG-0-)`RuB?{&M_8C9n|dpr4-8tcz$A4+N7!YQLc zj^c*mu@EUaeQz(YS-!7-ms`^-Hwl(NNzt5uf9tEmJO38b;N(w{nIQRAQzD0`#7)`v zDL9TZYR0@39e?aZ4gIA6s2}sBNYX2cWeexX0L~eKfJp{?v$9+qMK9L)X!!wz;{FR< z1`>8%7X-K%IRX>l&2rs7*AfDAP|Abyy$Y#y-CK%|vGy;{z^gxz-KBEHl(?0`t)8X# zvO}$qQT^Z!hOa1ktUN$g&3}FPj&+@gpMq5T<+LBmDO^!LwM6)x#6kd-t09%%{!Sf! zel&@Vzmn|!Qhw3nW$h^=L}Fa^kSALH0zcJwrzxf0hjlcllk5O(=-a{w?$8NfFh6IC zQFz(K{VKLISi+SE4li<#B*jsKNjCQi$T814#fk7x3XX~r9xHx{0vsJgsL;r`Ji|td(mlIG zS_a&!#M9-|?emLz*9W#@w<pSz#ZgQgn)|PGs8xV4MnDhA6c=E>F^@%^n-{S9k(Vj5Bx^#C- z@|(qzxeBf|%q#b3qr=D2PT70!MTTM3aEnxIYw}F`x@C8(JZ8#1v8a~k`yoo}@M~4d zU>(uJieEHMkhr{puf#|ENZ5^XW!>?FdHxj-1@_A-IWr}(JRg%bvcTu+Y1qU$%|9n^ zToW;mNI)C>pEgh4=M;y{!QkZ+0hei0HWKU$Dk#=%`4Q44Gz@B4^$fkvXl|s&jKVWD z3Fi=@sd}+Jj3$iVo<$VnTlWca5|zu7Po(pHqV1IjHQk}C1pHGSPt_ACBSSV`X>>~$ z+o}XnG@gVQ-?Kz1eX6IDgl;|;=6obT{wJ%=jiEZ4m{K-%y}h&u{e zsPc8xrP-rHUhkulA3vq!qEIA242bWRuhtU%+}rOLY#cbdbB8S*W5ZUz@odq9#!L)= z4BDo&bpUjj6LVY#jMFHZZ;H(T@mCz&%$!@b(ejKe5m6^MGj zAMQ$$`R~-g*H%!CQstnNbvKmxjQQBtA8wH-1 zSYQ|j$YNChnA%|(1mh|$O4P;a{6G^Wi-~R5a{QCW9rHDP4EcFUiY5TX&DD$8+PUq9 zl3Wr=biC+HoSpG1Fx4}A+ z5OG&1EQ)Ad7kMQiTh2kVup~jIXa+u(%^C8e73@=R2QyvuhwJZZn&Pnrp3vm%KuH%6 zHO23jEhw62lbOv=$^$8tKnyiArmA$HtHg-+GN=9=0@Jc?zsLt!jJN%9Dq1tvhi_Ip7?=(tp z${M!mU>CqXei^O9|HC&xx_gh^SoQqF9#7;tlnm|_WZchcGu`wpTp`f)(HX=vm8&_K zP{=T%O!yC8>eD77+lzkK`AZhCSb(6WoP_(BN7mZ_Gz>1%UGIE8BOTBc9zl` z7t=boB9xfTtd?62tQ`}1fKP-LwRD~CANhCCLIO&SiN$2F1g{0{iNkK+xr%v(k2~-7 z4LaQ#>YtXHO!@)k@xyr-<>n7QHnuvu#RMWd+z4>93)QuNSVG8A4$Z-1fT zraH#ooCG?g&FNe@#2Z&TpH@EK&QKD;p;6?C22A1~kTt-IgnpPzIVhC%IFdp0NdiiDwkQOs3;{`54qQ);7(SD1YD&5l>||FN|zp@kL;sT7O&*PEV%(WvpugpvH1CBX~o1A&cyxQ9m{4K%YOHPN!rW5 zX=7VfdbPD?ZqJWibmz)>sPjjNC#Qg7-7XL=@#JycUwkH6+s->~X{IueAPf;xLzX-p z7O{{R?FDVbRCx(Sau5Q22>g%HUdx9=qSm~((G{=zogw=@9(z)BLnh2{XBU;dH9epK zT3e2rPQA`kDF{VQupL9p-+RPM6b>g7$-wEV7XIslTR+Wps6a{ zdG$7S(_|;MHkLt?qHD=ZsJFMQ`98<`g3#ExL6?4<74?Xal1e(yq3`7HVQ`F`x+fu4 zOcVNzJ|`XKS0oLL+Ou6sET^^GQu>hLS;)Awf6PgpuzRR!15oo9@c`scL#4a|Ghh1+ z)gCSK3E2ssJS7N3R75`3*6}+X+Rut+`kk>#W`%@dP>mlYF@B_@AtDmWK0}AhZS1&4 zwOD$kX#qTxeG*3)h-rGe{242%=8ROFTn}m{ow-9oE}=4SPO_Lb^OIzY{5}~#Nd;&= zSsMxLF4%Cj{5>NzsIpukZ!#wr_?7*zfoSiYKb!$#u|7! zUD`j_JH{nA4|s5-KoMlqbGwSR1NX*5dcbdg1~a+!59oss&3^{Tfx?)nM>(!RuVv=O z(ET_Mc@le!sNg9z7LZQbh_zcG!aym!FB}w#w(5{zM-y^$1i&OH2DM$S6jZ_);04{4 zG`K$S8tqZ9qbsO+7AYOzX9{N3|95#}0ILx}5ie)E&NV+U|81Xp4c^W_aKEyTFZ0n# zBU2BpRqXoVfL;!SHObPU?INTC$6gf{;MZ&Qth}dg&^SlF-`Go5)+ab)1BL;>Zsb z`k&KzWD{*B9x+5?`CT|$IF=s6AA4Q)Jq-vM``+?F*5Y?i$HMS!Ti7bCZj3V1MmZ>b zX-8Jf;ykbZ&W0*|E^tbt(v5`oGR=SLx`E9X+#NUFN>jP2i?P*aJ4~$0l`+S$v9)jy zGki2Ca+I4q&2%Y$zmHq{qqUO%x2g*3bS$YR(qh1eNWGVt^IGx*yt@#9)-L;IX^=-t1dn zAIUZ-5X%vjV3^k;OWyIhVP$|XY8U?G^an4hr=LE~UrJym@;y`IDg)E4~!pYD>Tt*b<`);Wa;x`F57;C_iDE$lC*G z+x>!KD=wx|J$3@20-t^bi&Rw+Hz%Rv^V&Te(h7dgQX(^$CZ41!+N=9ODrSJd#lmfdrH@*V@iBT>9TBi=gf&-!so=4Gq68&Q$~NG z6Uv9Zjw3}x^A6#DLWtmxaTyr7;TtCuGS_NO>>gcgC4GOJ)w*+X>nzW?!crRQAoP^@ zX}pybv@wq@wOL>CCAk`?uH^gYIX|s@)ORvx5PDyrtwPe>(=~ z!H&mavr^J~LDIT>&M(F`qHp+P0%%^%hlmKs37p;(1mbN%y37mnrG+fXc*jxfBej-QFq8%k%JGmwYMW!l;eYs{gEGv} zW&4rHo2{aF4malNqBjjBX33ZuL*g|sR_LSTgSlO)b>y1F!3-p4qmipV^on0@y}YP2 zkeZ(83cu`Ko z$0qau2_^ij9!7#=hpPUE9SM~a(Fw({jibr$2oS$$9>`#m6<}N7m_>ePv@Zc}a=~kR z#y8&;P*NIuu~JE!s6H48A72nZ!n*>3)PP6if@qtt`i-EX(&iPeJXaLMMGC~7rW4W0 zRq5dJ3@Rqim}mwWaDryvG57|DWrQcHwohiZ{FBf3NlPW;ND)G+6N-BbDJQJl0>C>? ziSN=Cxx7NWRhiz}LKVwtjQ=j+J{(0CZVzxIT{RQ3onp+SW^Bga&fY~y8^rU= z#Z9m~D!GEcCZ0JPMg_ffX`@FJ{xTISEYeN*pfy~f_9C@irvY24?D5gckwTdYZD(JP z7%KblBzP$#8M1`yo(^Dk9&qNL!|d|xjipiyJ8n(-<9v=JO&>f%v6D4iYx}=BO+P5% zH6dD>(!0EIy%+Ym#^C1$3$a<>E`NGdVS*CBiF)p@0NCuri@A!xBpZDSwhs-ZT==5Z zO17UAG)u3lK22UiMX|OzN11@)^k8-2>O|BeG4qs+?5(9FcK{4f49S_u| zf^m&~?7tw%wt%1ZNiSJC2fBl=8O~WZPup)_jc(Ueu55j%lCsS&$(vvNVuLg9WoqX) z%Ky}II??V7(r>1&mMwmhZ}&<2)ncGqOtz;&>fBp;QRy$$2NF(BBOiDnB|DIdKty)1 zC7t3f`1y`L)2)$I4{bK^BUy~3EdmH^PDQ!mdy8H{|KrvUx6ytc1bO+u#XU_lT4q!cUG9!4VtEde3#6SJGj{+0|^`}Xh>Ch0orD)Gh}U$GDfSo0C!{fpq_jQzEQAWn4HYLnEm4R9Idj_q;l4yJ z5R6Tx0BXxt?%b8V=kwh;Z3!~@xlu<}@TBa4PH&g6Q_&X!Pb3KSrF0d4Zhag?#Xcdt zvy10=37~O3auSa-n=P$cDkHV*5n+A!4y}mIJ?Zna5u%T`_nBc^br7C;LBm;$RM_TA z__TnYw5*f6gnxE=YIB2AOSY4}oV{$nR6pVAVru~x=w>rB$$WhnHS?U{=Pt3k{`3v| zRj){e94Ew{b8NIUec8WPVRr#>C`<_+E{39lnr^;3WwQ>&5Y*R+#jaivotMZmR2sD0 zMq$`nJ6E?ue|s%@YjTUjw_BH9o_ei*XpLqmh-{R1v<>E9lVuQVqsL*X_80O-PWp}p z^&udZBvG%+)EZ&#tFUyrH4ty!jmLiC>BR#lB>v;OaNnc%(y+^PxDW(=Y$Ao0frM^Z zCCLVFX6d@7K3uDOfTkCZcJyLxq{Z~P^K9Bq4Gu8UoFEjUjRkM6Rbtg? zy6O>k02x3;Cw7`HGz$UAyldj4lI;i#7U~Pv>1ATmrLys%;f9}}zosG>%8S+-)a&7HblAm^ zD--==`Z>*9Sk_u_Hu4eaUY^rEZu?V8 zevhuXMR$605~JgrueM*b}Wfmo;L|t6%#WVxH)V%XOUM&*zO>l&G%Lq=c1P{L5R!d zbWQPSb8+N@*Uy9o+wZI5LLMM%0iMhh=s2i%KfZI_`cpydE1xvg?6T3m?Z7n)v9l`G zN%@Sf4{XWW(kkw*3r4pt8bx%q7+-4Y_}g_t)Vf#(=(~SD_7d39Y6qeYYC({K=Zw79 zy-;)RuzC6~4?Z0_3h7xH~hO3lp^fa|?h|nvBA+8czcQc+t9}N6k~C z{TBNt*#-lYcNpb!V4P1PCt@-T@K_7Z@G4ul$Chc`+_0m%hmJeLEvw z;o|sp!HINu8_jl93}l6lMx2mRVY0ddEIZL3reZ3jO|nf6H}%60(#BYu))8l*))wOn zy;$5EKV!fp5G-r_kzj4Q*zebeVmujGTS(`M9k2=TlQG}zAQ}pOAzR&!{b;q8 zncDAg$uiC_5m?@^lS#SlS$!wde4&ZQm`8Da#1jRJ)90fi>U}l7jAokq>C+}LImE8| zzwEq@jQ`9--v}{Jzb;YY539L}&tYUmY*v6|<(wi6VYwSQ=5jk?w=?%0dgIO-FO_J& zKx1v@6kAz3qF+hN@JAZbMjw0oyAp`Ky;lPC1`4rfAQNvpr@?V^4w( zX(!NaE^MV5Ff zjPubBmEA^9%EQ~=v0Rcui+l~xUs4U$Op9Ay^?sUEkW#-R*OS?z*>9tpSF04r#;w4N z(<-(X+fH7F!_v)?Uei^!)hpJc0qr<9rqPO7j|9%ZT5;UZckcIBH@mZl7|laEc}=D) z6*K&u=n|`Tb)VffIeLzTo928h!D)41H9r@LM$f98FswS%7|W@Tg#1ZuIl%6Q9GA1;d}U z!eGbEI9IGj@W~JTK8pwXx@Nd5!37r;dT69iNT`B2ICCWZ124f9#o-Z0?CLoWlO6lB zyL1?Tp84{h6c#-%o59cCw#+W7D0k@6R5Kbf!mC>dY|B4BclWcyYQ);z?ohuymZY|p9ZtGL}mGs1H2Lqf8k~x24 zGN^N5OvKRqL<{$yD$ci5(hl*{AnauYpi})jHEVkpW(W$Ec%CH{S>r9(z~hJ|lb53O z^+pZ;Q0m0OmCbw6&~xEHN%6=!V;WNEG+R+!eQ4A1Aosa!HN2E^dC&7RA`1%5-9|>% zx)8{{qaAg<^kXddU8|Wtz|xH-WV@D5$S|iBXiGlWnP!PXv~RSID->yE5_NP%1$9PV zAZ@1slN6xEd_9>3zei+gONO^Eh;x1IYz#*9iy!UbXu|BlF*Eijy$5*X zq6OriBzOx%#b553pa-#$=|8ZbiOed)3d|o>sC9{U{@tu z5feo(h-~mW280KZ)Y$*RQf~Q(Ghv=^NGyrcB0--FQ97O1!98)rL1}$VR5WQgIjTNY zr$x0gV!TF}QcV@@oXpF@F^rH$f+@3Qtm=)IEnsGGOK!6!G{gZ3Z&G$Cm>%KnF!^qS zS5)xb%eCzL);>9wd}R7G?$L}GlO>_MZ&fA;;hxp(IhJ)4k`s?Mj|<8e?-7i3JfKP& z7a6we{Ah4>+;uR_V@Emfd6d|2Iip_|3^7RY7(Ys1r*xh0a69nExiKG6B7gG++q7oc zEwwo!&!ms;qqufGWgFXS`AxZ2U(>4Wy*$2{H}xe)zX1a?51?lmI#X3 zuYl>8#F_wG8ni`8R|Yq<@>?FE(^qK0kHUp^lN7u2iweg8dW{T+jt~@pSsi;S%hBJfROdDqBqY|}li18T+m(~nQ?+72-Aa~Nb}M|t_TlV<0A zbexLIez7Ot|H$2&VR0`jc)11?iuWUf4bk5*4S39pY#(oA1X;BrgJEu;wz;84P#a**cuf!+D4=YEf1E2%yN(Jr;7=PP`vZD(QcPVf`5S`=I zrnobr7^Z{Xo`Wh62mpOv<1vz|O^zqx!2m1T<|*3_PdL8_)SVXwi>FV zRdv^CXnXG5aDrKfP3A`@t;C9=&uN9k&O^>H>`$231Go4m`uJopR>RuvYO99U76dYW zw?liFZ1DpRWx$oQDM>gF`}uNRlsYL|6rFQ5$u4wBWDd+DzEP%gV7imY^D_)P)-dL9 z(Hu3er^uz9|Jnn!4I2mKf{#s%numbhc>QC)e@B*#fK?;S-4?btVtgcr%ZIcPYL)3F zw5jhQ68jyB^sQTBx3{Q@9fAH%HH>RG2zpW869W$#kmHQMdtYkKCcjBYxyvav@mr%u zYrrAeu?bVjA|`qFai&-9I`N%9G|FN$)&u;t%$O{%FTo0zyH}3D$BS336%t3tY!~`o zR1$80&^ogGD(zyer8|v>tb+RcTnyV;QheeCBQ!lR%gAv#c^tjBS0sVn2y@waIx{m$R}ROfs}w;= zdz7_SnP_hq+8@(*J~O&cEhz6e8?}Wf>IW-nX>F#w05i|5dv)GvZrOP|Jf5s$)um0- zkoWFwDF}JKimYzViNR z&KnDmN0!JPPJAq_%P)R!5t^USOpzddC~>w;f2=3azd>j;D00)C=>6kE&>=U(Qoq?E zUjFNJ{dbg);pA#7P;eo^_hz|<`mw#K0&F~S^fdUgG0G6^{eE;@NWfog*=eh?<|<(- z1WL)32iT(P-8Y;1kxee?bzQS_4xel0lZO5p_6`>PUq7t{txl_0KeaZKa1JUzw$s=@ zTtCq?Ta+hL$W^sGm-Da)#Y$tTU>y7k>whH&X49`tGV*`2lpM?%0bsyal8^zXYGSl= zCpIjUc&fe%k%iqc883+LM2>VJtNBz!vMZ-tA3X9~emTbSM4P5W>AWs)cc6CGe6L_M zKln-;9JC4IIefoiy>zgtDIwRVgB*7#wM!L+*58xpb92?%w$^}7d>z$b7*~9t1GQ%| zLO?Q^Pm)(VOA!-TS^KBFUvhd}rcZbrfD-)N9sq@`zsZCkb^<}CO z@ZnQhLVm<`fOd_&wrY&rbtPwyH8;^Z2-|~`g~vG6;uYH3W8iL zQys z!;ZDSk*4XV<3WkXIgwWIh~S~hwdu0oqMb)Nc$|$nfguLk-c96L%c(KgM=)6Qc|^aQ z@MK>s2sIs)>XQ4OhL*gRhl65oLPA8LRcfqmv8_o(xEJd|7+I7DruN`nnZ+tW=q8wo zzkNF+nG>AcSq~RMUR?mlI#zV_6lwI7my{r1bD6c*ur(brO4hGgh*EJBk29bg6Txm- z{rlH+J&snaTlu4jcsO7rmtNGets}7Iw&6PF??9zV;k?~zG#yYJG~f>bK;!I_P4%OgKGr?GN(GSipN?McR^9P;!tujlFzph9!P#gEIig2xrIP+p4PJ|^0p>O z>I#bi_k^^UoNAZe*w3y0Zax)7Mlgyy6C2Gc@5K2E%X5akKT~+eA(u(a->}3R{p+xw zB{M&we9jrvLZf*Dx1C!$@P4)#-6YoaF}nD>0uWk7QANK@YBz_vN)Y%>Ilh8JCG;{ zZ1~w?fHLURhrOFMD$vySU386aw5JI}7?MSkQ+3Kjzru~87z58MPKfXhGF8`v>L5r2Xl#j^ed<5_a-mNgY0+mqkm(SMlxGybT}LWFBAX#V z>QH&_*TfOpbXdux+!ockIQE5E_b`?(hxK4$jMvR^hrpe|woZBQ>2(!A&<^zzbXtn3 z$F_)yaZd+&2&ekw8s-$>@eX6}cl~}`@8BJhasO9~%e1ceu9$E(ew?dY>pU*#vUQ0MQz&{qYb5Y_)|=&83r&>b5W%V>$tLno z)?~jTTXNjTzI_ci*e^NmLIPLFvdX*b`iy`t?Mb} zMF`CZKl^Y$HyM6)gN-%15FnlONE5I}w$rln5+yLOS69v0^<`v4``uAONMLsvMVCni zTJFn84@)i;<_ZFIj-=#|y}Fh3&E9{cRwItc@-M(X3L%3E#X;GS=IV%hkgrLL@%Nps(TXh~4$%&*J#7rZBp@ zF98Fn+1pDI-HE_x62`@7ZKA@JS65eiq3jQ1z6A|A@)Kb2j3eHeFH?O*)-P2L`IAZx zXU(o{1ZUmM+C#Q1LIYJ%`U^p$!JjM!k5zD^%cIxa+MdInfe{{|>EBVIBP=3HFL)W- znW_vS^C!KrXDoLMjegl+wt>iFhZgGqCRF?A2aI7H2;0{(%`ji z5RvE4$cH_Kc#KQF%UKRo$@jezEB%?K#^UH9j|R4q6p)$C@1$Y?vUwX~W(V`%e0+(q z?%-&=0OD%sV(YxJ&N6|lyt4m@k$N!X2hx1{=irO0K9o2R8 zRwmZgEY<839uCXrz^JbkyB1l=*=6{5Cz=IvUF=~*$^1QEHbM#QITpJ7{+3MIGCiHR z(Mv?5|;>f25{L^y9l9KCxMkPkmm72_o1%GwyV`K4Gr?>Le)mEa$kNqq`k`;?uIA z)RbvX3qP(Mr;&X9OoR1ZRk+v%7vA|fq9@JNDKL|bgdOs1A@st+`O(p`^ug##u{#MtlrKVS}*Xx!REU{Bq znK384J#(HoA7!Y=0!$okrd`=9$CzKn52E#*I-|d!_tU7EKsOV&h4A3Nk0gLKYjNke zpY$w+6_7NpyhbEs>kf`N^JrQ4>kJ5M&bUbo4P`EwP;NsolRTa)AC;Xfg^y?5G0SS-23u9s7IP5WDo zn1ZZz$&ij636bbsGtox`22EuV{O%t7b(~g%x|pc2?Aj_ARZC3uWIX_K)*F#tn}GRZ zf{c7VZSZvV+@%4niNO}g+@!wOnOYR+W?9qwuKL4y#m(ii(um>X)yj_Sfc=5|%l?o; z?q|7a`#sJX9^EHW?i$%{9cHd9qa9~P!C6q=Q zoF0#!ePhG0=f-7Q+E-#)PP>TI}`jOb~lP5;`^{Z@{#m*a4q90VrlgNpFiP_4Zm#>= zfYnYPgF*0nZgPcQ^l)0MvkGtM@BJN%-V?gQbbAzA0aZbgj_^#3J|V$jGiTKM;2lxD zUc$ACOUC$79k3 zcl*6hltinq0R78pJNBOO{YH%Y(AUiaX=*og_eL9G0E3B>P2<~dp>aH?#0#L8QF&m% z{rJODd$}Fr9@RPet!gkPUQcz*q6DF7IfEETB38xSvVrVgd2gZ(omvpzIL^R7MV7S$ z?QI+Kf}RI$g-mww0^71M=?@s z>~*IF#Cs%HBo^~P#eb5!DC=y51;j%Hqa3^+59b-1Lwgn@LrVPiN?*1)*EI=LZEJ_r zL^$F5ZhsL51=_c}wgLnjWI)?Ad{)P&nop9`a!HI*3kCrZ9`qEju7loF z9?G%Sp9DUw`PG`?Uo&Kbb-L*EYYYrFh+i+pK`V*>2$9)*VehZ1*rZ*i&rNOyk-$wy zJ2%?Cb-db=$#33o>Rc06h^8s2jfKT8$>pOaeDlDHYe7W2Km%HRO$XE26Je^71WgCI zqr1V5esxy(BqKyv{Bj3HtQKeS0F*&Ru?D6?N3#Ugtl1wB5Ruv;x?pM;mpqkfz#mu{ z7qG;;S|q*s*-f(F3b&hxfo7ubAJ8#qFv`qheiOsaZIg`8-Yv3~Xp=QV93!X5h$oER z^LGdZLuGyAV=LmM;DO&AYU13Qr1*G;cry%Gl+_6BK3=}xBX3lTTEBJ7%q70#Y)1aF+KLZY7&$9nB@Q$Dac^?-yJXBR4r0C>y8Ynk!X(PJ#J^b& z!yIuWs+EY9UC(A3e%k!*&|YtK?0ZJSm$_h4i__&y^y9mdFoBskvRrCw--jX&>|pX@DyzOl=m21Z+=O_Yv81i_-y%Ke|iX|BH>nEjGL(P_~jT;8TH8 zS?sSXuOb*hVHWXxB{{}zForM@!4{WoR)nADjhjfZ=3@H>{t;h%xk*4K?>g*Qv?Z&H z5*0#?=r;(A4}L^JBaP^KMNF>SSBnH9_w+&D+(}9qy*Zd+X}I4AGo)Wk7>*{W;1MGhDI4$G34zJTMEJi z>&Rf!npT|>_Nz8*v|jGli5$RKgt?}Oc67ph5DsgBs-b|7?w#j=H%Huwg<#;m;P+&n zXM6tZW6&!lF&qgUk?;YfGqN6`?h;Pi?X2u`ir>gW7M}7HZDy06U3&4jCQM}_$6KKt zdqB%An_t0&1ZzU|f>`oo^Fhy)#m7$D1wv3_jIg&zS$m6Q3%GnwMmGDQ?R*&a4bm=2 zC-(HLuQY3MSpM$%74;1?3K!agF#rIr1_QR21~&`3Jk*A}Gz3eJIXy@>L!fpg$~nd; zp`Hd$yY=gvTukyrP5Z+TAXV-;x9&Paruy!km-1>K#R1;Lu}1~Le(Md?uTO4 zO4!d(n6*9uUkUV%G@`hVp^KML?BiqoQor(kovTbK#!`yQdY1D`%YaCa3c8@;x31b+ zg3eM)B|sK=!K35bZNT|q5i2A*cK9sDGb>}|bnSeH=kzJ(`%Bm_+IYcO*QG6;(5lv7 z4$FbUw}n~$WU=!UXiH}cdfF5~U!z%GR;59w(_rh@{b~S4LxQJRFx2_96$RcQvNa-m z-9yRNRTYy1x%rwG#i*4^P@)xm<8?8_<`V(#9M<=YzzgyDvvgDCK-eSxnbUNz-99Pd z{v|4c9^xQnSnH>FAFMi%K2fxu;Jf2(%QTRq>|&4g!c|hBm;n^2lLh}yTqWmwm&g4( zl13iu#l?;`wrAhJeJoVeYj=$lGVu5M1+6)M>qYaE1OWot>O+g{M(Z~f`x)PVDh7|0 zz2#b1wam3yd|7f(>d@wtefYGaL#pPUYvSOcu#|mHwHAd-eOPTDKgCyP?Uta0J~&5U zG>Y8AAZdRvwQU-NcN;>$QBYerF<4b1<}g(W@-lj$V>cFLb31w$y~8$7=@J)h;Y1B? zG*t}e#FBLXO2hHGSL!Kb|N54&(yJn3@b3BGLw_kwrxajd%&z%9Z|HC$YGc;x^X9du%|fxf)b+!iMYpeZ|BivlWDb#LH%C&l-@iY{r4GjFYN zFk=@l6$28)1&e$7%Ya-@87{4nSXED#F>bsNU$IDVV3l>E^`{?6Tay8$UJ9^2rx5L+ zEdWVrtrpns!zLyZ_DI%~nZ5t>xHf3v1$9CAR_5ppz5rPpXBEH;QC#fhJ;;n#kRkmg z5+Ek=`m3kBr0CCg^sXp`7mVRxzrJUr6GV^|W9qA1I`g;1X+G%v)@Sat6JP`TO=$m1 zZceoGDwhcb^(RECf%o>?Vy2NkYsY7V!JYtZqzIEGswx0p=`FCMRm8fxE@Z|H4wJ#U!w;x%D5ubnamQu z@|MgV+~8_5IpIJAvc4G!*brQhx*;;vo(i>S&g&?dzkVW`- z%i3%1)ElNsD`b`#$xhX3-HEXoAYR9uZ1`TB#)8v{RnU$;L05G@1#ksotc1V07?y?k z<6xN?dcI}Km8L(kPX6{tWV3#*9Ee-xBuYU7^gSX#7GL^LXqNwZA6i|HJxi1FIM$IR zd4I?Y4z+2%HZUgk79TV;|F4}KgIh$L$SJYCWa{h)__^RDL?+3GDj zIveQ(e4v76_>V`CC-kRo|4WjAvNt*ff5v0{4jLzsP1+*3-)ska-Wkzx5M+cT#2w)J zy~*{$*<%`HJm9ZYIeSx~T8M7Ij={85H499EvuzK50mqIKF)ZCM9sRNeWJ+$rN0p%C z>P8Rjb=`nOC*i{VxIZ({{tPu>qPApEFOx;XW8S$L$oA~?bJ(d}O4O#tGX2ope=3z1cUrEvZOt&Pr(*eif1M-co~GaTbN?Qb(J zOpmdZYq{ywAEM)8qJIhkF#`^Ad`vVD_tOPtQ|bR3LLQU&8_*$Q@LDi&I2nb?<-xi- zIb&4#X`8eK5)|(L9b574pnqMhT^AY)1Im=&D2qv1@n1~5lvpAQmpavBU4$!@n5iks=9cI`fWfTL5^D67u0PpGEF{Z^5osy7WMzaAv>cXRE>YOIDI}eJY z%xh)cEWEC*eA<%O808qx@xCO)hlG76X^C+^J~L=!?oi=sq=*&5D(amwe)+m-S?v_) zxZd7Pls23AVO{>86x)COk>x-DTHQq2FW;5umROF~`#WrbE*1|!#^a>&{T9pzpX_25 zJ3r(AQ$pFeKAC%CIw~ysFBSK8{4HL_wN(FXW}WwcxJ>4A?zQgRQcc3;$k8dX{cP># z5L1M=-fl-@_DM_Jj8LN>kSb4yTlQNqh0Eu42af>hl?78f-cQXjz-Wi~0yCUJU+ImF zZPC97ys@tk&x~5Y70A93D&h-xxC(0j^%0DvHvk9|pyrs2s7Nv=&tpz2!EPLN2d-!h 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�g&tH#N~Li6L29?f`!&w7L%i^Xv~ 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

<8hh>S6Au{!Y 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 literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/evm/remix-vm-injected.png b/docs/site/static/img/iota-chains/evm/remix-vm-injected.png new file mode 100644 index 0000000000000000000000000000000000000000..6d2e4c8e087dda3522dfe91fd8f2093b8b4a91e8 GIT binary patch literal 89635 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

&9o5MRqhiibAf*YwCDjbdo@NWQLe#BL( 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 pa`Ifd97Hnf}=O|U3O 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 literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/multichain.png b/docs/site/static/img/iota-chains/multichain.png new file mode 100644 index 0000000000000000000000000000000000000000..2c761f458668d16033ebd68781bdd306b92cca95 GIT binary patch literal 38994 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

005uhW%l&7 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%0D*gn#JzA9AR6B= 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 A^8f$< literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/tutorial/accounts.png b/docs/site/static/img/iota-chains/tutorial/accounts.png new file mode 100644 index 0000000000000000000000000000000000000000..827935368b1e97ce9b1b53143ecdfddb874cc8be GIT binary patch literal 62709 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 literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/tutorial/call_view.png b/docs/site/static/img/iota-chains/tutorial/call_view.png new file mode 100644 index 0000000000000000000000000000000000000000..6ec91b9935499b6578fcf0b9a8c39a306936707d GIT binary patch literal 49904 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 literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/wasm_vm/Proxies.png b/docs/site/static/img/iota-chains/wasm_vm/Proxies.png new file mode 100644 index 0000000000000000000000000000000000000000..5af874582f3e3376823298743aba2ea1dcd79730 GIT binary patch literal 24052 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 literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/wasm_vm/WasmVM.png b/docs/site/static/img/iota-chains/wasm_vm/WasmVM.png new file mode 100644 index 0000000000000000000000000000000000000000..2cf870f93a55f54850c94a6249e6d586879c949e GIT binary patch literal 18482 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 P48c1Ypv=f1sP z;O3m1oNRXIKf61&v%g7{x~e?p8)47j{ZNt0?l6$PmYZh+?B{)2Jq?-Z3xRx`h2&{mOFrXQ6GeC z!I+x+>5hqVw3Z%rqwW?M@rDJ$Y96r{myC@>@4{bZ{_0yUiOD&1tiV6j9)nB;+>OVP z_Icr9-4A~cQbtUo-8?!B8f85eERH1cr2Plq>M!b4rP;0_%YGdbJW?L-CYf>V)ia#3 zOD^VTKQDD8_%O$u(oVeeqk;FM0(736@`65#JK!NNtGV9d7<7R z9lrG{FKoP*RyTG74Al{hKK-NASnYd4 z0+w%{3Jnpi5fc0dHC(Cf2e(}{7KYqa2IQH)Gf{r`*w~a^YAb{;oWKrE&iB!3UejE8xY8-OTR@C@|eMB;9mq~)QzeCbSQDAFunJ{ zdg+fU<(1q6jzqTD?_0V5UkX9xEIZvNo63=$ukBiqCDtvknnk%5&YPY>Dnt6~?f_SX zbBB*X*8H#~jpk`T!jNX&iXg_vE?*P6j98{>j6qS1xlxx4fi8!yJY*Hl&RutqKT*;D zk+%Jjt4Wim^l0}(wYwB`oJ0^KQ$l;ms@U5}aZ%zf^)y5#_@}4Hl1S`GmqnXN#W^W! zqa=*ciFB{Ad*b1KQEcCY_GL=gab?xH5+|Z2#EiA8l#=)!75u&J6k)r{wzb9;qd;?9 zd|M^jQTtd(K|7^72OC?qBV64PzM#Q3$Ub1V21?Ser;^+1e&!HHl_A(xl}Wk=o4om; zp_lcLSvJQ>gt}PM?#4Nw`m{1a8sN68g|A+4hz2L%3t#Mw1jz=%97RRO?;uqF=D7fv zD_-c3Q)1m*J#N)p%x3nTK#pVy_6w8$_iMaXqYmL0PsOE&$8-hWCA0PF+I6)G&2idZ zURrF|vpG5G;j6~L^)P?3Vd-CYm`>X^*%fz>;{|um#xb|kRpS!>O+^_Qc~&UkhA5S& zuz!hL8r$x2OB8owB{=T72z?5G+{z>685W`1OY`e{8Fc{`#H_UmdIuvxL_m<-rY;?e zw-z+8l+P+AcONd4&U|+sWGUScUrjdx+SXp|o4TH}icM3;)*Y@rK zO~7`5lQ7_QZIA-ez5#hyHIfHmkK4%o7XvHbi^^%Sg*Nb4GamQ=f^WIPj2T7zxDeW* zw*sRLckdNt`wF%N!D7J@=74j8PhHZsRt}din-_^l=97!Vh*7!bnN}iBL=@;=y0~L; zx^%;oTAplF1vE^#sgaBfzP=pUv;KIAI1b+g$q4uaqGY+%5{Casu2@!PGPIb`65D?~dO8AbY{qRF+BgRF1y8Ch&F3MlHu%fT6Wo zFKmD79H-nSJ(=R;VL3W{zy~&(f!?D-ARz%QdiAcgjd#kpv0o0u&lEq_oafI=qNoC& zD5GgOn_s{5#Uv&0XbgP1X!08%)vjzpzep)J!JBe1y^R`F%*itcH9MO~D8M_a+YM;% zMzs?uge{uW8-GgSFfu9lp?FxF82m2+bw;>@v3$?~uH#>ZWQv7thKY1l)J1}3MXy-2 zI~1*|Kyz0P4bu+N4@w`h8uLkv+b&6eX24e>4f%CBMt-*!U4t+TRy2l#>rr3k^t|S9 z^P20qCMYRAv8#sXJg`eAv%;GdtkkviaLb>p--Uh4e^-|2oSEBFMJab1Wt}zZaklmE zn@l363x>zzKWzB`Fa)?3{D27;mft;+>MP9+m$pw``3pA&=D=dTxh{)hC=#HUH2u&25MqFbq8XzqOI=q>Ojp1 z$$qw=)E!iAnB&s8YjVh%LFHxfyv7)2vvEsEP${7c4*plO^at2mk6r!#q%3tV&H44 z*Q~w$1+ZTzdr=_XI~`HO52v7QupMS!RbU;02tpMm^} z|JoTH_X5=-T2z906J}qW`GD;9umnXKz2`+kxT^W9gJxCW>v|s#T@z-Mg*i;whJl*V zu};cp-jRsm(BsXl#y_;H1o3ctKm20v>AOUZug~{-eN+0 zMK2kvJP4wZnR|L|h#?`Ugl`-2+3D39Bbl7dD3Upao}D`XBH*u6cKf$Ga+b%n_5c@; zpm>J36pnO)1kx?Eg9H^yt({~WL}IHp&!8@-~9I&cK~XsAU?Qyp?-L;UE(#v#{un1u)ZEs^|w|_!(a*E zsz9z-yohC(Uy5erA0ZeextpB8-Fvb6tJ>V9CvJhW^5h`&(wwWpc5SFLWdT#89;j!O zMmRQn=S43Vq)mzqKPu~Wt@>#*!Uvt@yGwx}IYZI)hyr+~vXUyEu!rqmp0ws%ja!9; z=T(K^)$l_NJ)V*FE$86alAu{Tcz~qbp@=eTvb39Cblpt&+!~q)>+^suC-b~mQl0C;4iYuzp+2%Kis3Tyi+`7L zfQI3uO0BEN7e0bjMPqP(r$_AMZa!;XnjDH@qpQ1{ z6D;DtFVAgnw1MdXgcQ4RRZS9GG0;phUnJ(SiB;7++3%_mrPI!(L_*7KKPow#QNStH zs>5=HSF-jPstQh2k9vB{vc-YMpD5CCd+8i*_$6RTtgNQ`;BoE-i{PbC>6*o_(+`3g zl}7cjDP3yg3>mTGXKQ>Yg03wpA#h?pt7f(-Gm5V3gt)lVHIsr`%DikUm#_~SWvQvfw3izjfL>FN#iWSD!*yj72O`Ul+Tn9^ZGNK)TRKb^6FGlCq6bE z#S^J%O1t^{hMx^?J$}|SN`X{Wc`37o5MUMq8ZyGNGtvEv4}?N*R}4B`{j9Q7;%PQ4 z&J?z7GsVmnsq{Kgnc!ls95)5gE=k0fuel=+CY@ZIdNm~eE&Z;<`F_8dhc-ll2WTK3 zvK@a{DYsdc$<)dk#-4a#yQNy(}Sihh|J{#8lw~4!HOOg zFnUIZ}~Wzin4{PD@`rPoPCeLFq4%g)ZCT$2Wgev?HULeIO&$g_nopCNY$r5 zpE9oiBqUSTy+XMgM^M(ns^8Ys4cuzxUMS*fhk!5V+TtqXkVZA}1zX$iCQ;qw0|J_v zEdc#a*_X5J0yQ~ulE;1WP5vJ;q?+KP{=F_De!7T^jFrI6)2R=a;&`Gj=#_I=Zk3{- z?{4fNRTBxwp-H>m?f%7V1_x)M|5v+t8h87b&meAO6e@uOt)ejqr|@7;NN&chy>tsQ)SIc3kbDNTPFN4+ot?Y-i*MAUOy-upCmN#k#1wMt54ikx&;`?qFGzrJ_`h(yDa}Pqt zwKG|vY%5H1DW3ith8T?Oc)k{)tEf@SoH-C?+8w{8&pT?(;?K1z|KubL9|hcN8COp8 zk>R@YPe;n8+$$^}{zy)-$(+9Q*}Lgo4wtkqi=wC0F>^C;go z4oaSXOPF_R|JJ3bMRzUW@C^4bA*{tfdO-)c4(kQ{h zg<3fT1eB>q0XJ3*z8wK&JSQpHopb|yPAK)-D&#rsbdsRG$vfjm6h+3f%kxt-)cDmI z)qE~MN#eTY<~wWNuWXS~tS){LkH4ZRs`P@Lg=jLZ-fH(&VIVZ@=gU;OI;aJcGN}tt zSYrr1wPZZxOv$CjX0;uD*6C*(niScsUOqs>q@8|5zi|#ubC@H{y!T5h8P7&pt9S~@ zzMoD1UJ_Wd0T0rHzduUe7w#4=+*rha?3uxdbpD7IHBs$1dXk|Acz6C-4-a33LbmZ4 znp8hpOO3DW)CEmF=QIU7kI`ZWfNvFM*=>uN)C1xll*dt!8jV~IJ$U-KQ+K-SI`u)O3-;Y1r^T~Oc;q6&G$`dJ!q67=tEWE~D?=Qi zQ{v(FEGVZ{1^@d{sNdg8+i)lLw|w&s=?G5^+$h0zl5Ci7UNi15J@KT7`XoHKj3V2Y zjGOx5VSqgS-P1X&QU6qxrT9jW<^IYRBR~2>1Mt@>!9h0-+FjlzZ(MCCASE3AI#)z_ z`w#|{5GW1b*=bva<$8><2)d0{zf+|fg9c|rS8HuW?M3ms4$8@X>{pC(kSIVe>TXP- z$e5jyXL!9dAfi4)we(=X_jN4>z1GKbTJ-w*wxj~Ha`07gv5>wPK>S&%jPxBcJeV++ zIC3Z(U0UboXIfNf4>-fj8MZgzG&n>VEqtyRT*du4iVRTw8%MXHnSJCUz;|eu;v>d6 zSZQP$K(-{d)Ar}`Wc>LNb13>2BX}e2k6H{}q7_g3d9nh=)-~F6h9vsBQIchy%0x*f zluL=)VdplUm#O8V^k=tMoD|4m4%-@Cyd5`VOVYX;=h5p1ry=Wag+{a9TALpbIzDX! zJaw;RG_p&egz`q89qNSET?vpZa#Sc0dtK{>8*Y6?t!Oowse9a+TJ>b?+8tgGroeeX zt>xICJ_hBCoOGJ(MCw5I$pcC9?*X_*93$sMU1mB;-vt@QpTQ5hS%o=05ldP*` zF3TA4$krtS;L5;)O*E~2KlQH^fMR7uGnDK(_Di^FRxqy<+c%}B5#w*&}Uu=12 zMiMK8C#+A-mzx%PZ<@r{Y#shNsS=ZJeZ`8F0z!R9%D+zc?rOi=##4tClXlJ1D|MNw zc9#bL-Nm7$8|Qq~?;^T3m^82u2?WZGc2ZITjO`5N;pLo%;|9|*m*Lv zSI071LO4*cyZci^lEfDaof*#-!)VJE78~2Te3)y=3LuUtK!hHRTzNNn?fZRFl#T<9 zWwf3F#6#{-QQ%V*Hg8@TV|o-c;ZH}jiy>8)=&u{sxbQOmFx6Ry-0#ke$VCWaQQH1n zm->aRtIhuAp9Fa0PCmn0uYTaIt0QF=^uD%f5FgWXq<4XhY&m9E{}s1{oK}%2HO#Rp)yvqc z%PO;>(!pa*g@gTIOX@vfe|uqrtvUG{nO#ZQ8- zidRL4Pl%fkbL_x|WFI)4U+6RSbNd4*hmW6=!Y=mu%B{H*N6tY^?6-V6Dk|&7HW!5O zi$V6D)4eS=xazmzK2Y38jzj$*i7{$O-$OL%Wcz&1?t^T{1?+IzD|Dog53+7-i%OvF zQ+DX7e$sap2M?Aa<0#PD8vv-Z%3{+jfJDCekC4wTPeU$9%BP276^ywkLa!C`q&6C}E%4Rh#sL&ym40Il`lR_j4m4SYv#tFAUs z2?|R;ucij~ClL(k20T-`9P`LOt}M$*0%=!zNHv@Mf4rI;_cowBqy4B3&gmT3*|Fxo zu-BP^N4XB-fifvQmiGzJZ;rF~Kq>Z^DWw3-hn~ta(fOcCMv8VME$!)QJhl&cjiBtv zL{Y}aa^S}a8G5oiW4Q7m0H*%m!_^M*fz!b_Q4u>tdU5JOzo$pCnK4JrU zxw8YaUgMm@F(tqEM7zZEEU9Mnfwf$q6qCtkb8_vi8=C3-D%KW-p~WdjFB~GCZsghO zg=*(z%zMeKf*`Pj$1v6PeJLP$t&q?A?x;{LV?gT|BC;DCw71M}ZUTZZjEMc+397&Dv;2N|2CR5Q51dhuTtjpzhgh?)nHz;WwL8K>zUq9rVB zUKf>X?s!sACEg`^u7yvBWok|6sA$#80(94@pT$8U)O{=pW7P7G`^uMwIW;x7dq`8< zHKY}}!rmEQ0IW_`H&;vVDgPoL0Q7=(o1e|V01tJ|c9!=^4uwRuCSmrb-63aHSE0n3 zG%P#%0c^M8t2Gn#?>YMKytNY>e1b3IFDc4{bz93qOpxatH7?mk0|e$IihfKun^44B zg)L25j1^6v8V4KF04A}Rw+3^!Enl+;uFq(TSbiAg#^PtvbVCFwrhK+8>91Z<<&i*P zE3uc*xT;s}6+0Xg+Tk_eIJB0_se(St>DXws4`&~`d+`+2SY5>#?%$Q8S-U$>miI3% zEbLFIoNUf(-K(6iT1^_rAUP&l+BvUu1W&Pc85d64FgE6hADYk*5571EmldO~(%8B= zf1mU>8)CQy{orKHd+Cubm;=&n4w8ZwL$fbun=rD?n`Nxd?o@?=& ztxHnJLu#F}TS(0s@02)D8Cp|8*A;{t{0oW#EGdc25dTgj;L-K_kQf-q5YlD`(KHa3kx zm!4B5UaF~4U?Q2mJXU5-_=a$DQa{9hmHW52d@y#eb7uYZC0`c9mae}-Q2VB0_;=BT z#f~QffcuvCV{?~K$GZ){)DqQlQ9C{R49=OMmU1MG5RY9J zq$7{58`ofV`yi|m^tR;eNL|;R+nWbIhGmacro~fVb-WXz6=lsmzo!$pzWxEq9o%$v zHv5r#&2+jRS)u$1K+le#3bpq(6wV%)imiX^#heE##EOdd9q%0XU0^J9JEG6M^iscR zDm!%bqEsqU%Ng?*j*3`O9Pf`n>gTAR7T1+WCC4sB*3UnUqxD!f^p$29OmYzVq>1;c z^J)!ytd7j%ye6JA)V@xF8bi%Q9q3ufgO@8`1{Q%DgL1PgR8~9o67)9uw zKLWfT6M*ThU$wj0Q$y-^$&|?5 zuX@AUP_lRg*Q@m3voaOc)HPM#C1`E-!xqdw_j*ySUbHJ@ExNd3FO3WV87Z5L$= z&+Ga>uFhb(^A$SuLUt*ef{X^B^1N!um%^sKj$iHZVxCnAa1_;@g1Aqh{>i>HFK}yD%vGl9be(+gv4}7?Di>Bz|I$vxd$_9k&O{K8C zU*3}YU3F#dHl|5A3kntU6vbti8MlvR85(r_$`Z@qB_kAGb(Xsb!t$^?m)+)>jYtiA zT?Jiw!xrD;kd#B0_Pnyw-@I#b8VLB@1i!s?FtbafPu#B7in_C}>Oab;qm*E>3BFeU z)F)2(F+M2PF7qdhle&3|N8|L3&;~8utA-je4|c@KgaSNAeaA#of92q$MhB?38(PGV z1({g8`^!|02((!qUSme3jptt^WR&nk>Km+XX~TdDtS1|X%L0cUVB(H!{CU)bWlc*1 z@4%VuXoW>nn~F07O|ADr!S4-D0zRBzz~RDN>mu^&Fy&Ge$g~xAj&H^Rkv$9e$wPxt zPh)o?B&P-t9OWQ&Qwh;bbxfeCPasR>^Z13(J|pPz^I)zO&1nsoP}f$MBa84;jk*h zR;-6~B020=(KU;NFVS%yYvKf;S5}Dn#RF5uhjPlUX945X9`m_em_v*wfpwh@T6#`e z!v7qOJWH#tV5IN#29jMbTU^rpju(O`#VTxUO2mwiEeEDi4&A2aig?2<3kc80o~TIE zk2wA84a*Ed`3Wk|ax-Y}i_dgMwGS~yf@+mW)J4Gh^v)DFY<37oHU+r-Q}c@tw*w?H z>oJe|`cc)+@Dz|IX65u?^mKD+C{5%ECAHcxSu)&W6MD@G11GF~N0hel%_k4}s(%^l zv1x1-NqDuqL`_0dbz5p8Knq4j7>VK7yX$Xq;LmL4rXx>O?WP}SNGv&W+T97Hys1Qw z-}A5pv3<}-SdlmymIx2J;(I&X-o-hr6I0L+x)vN%XMDEEDJr&gX;k4|_8NU+p!LDV zk|$;`R!n9vSpR0d&0A}o*Wiri>tVRdfhJB997tYnAi-etHCK2&50ssv^RqqU{D_hV zlOz$M)uk=oO?U%jYfJtFg1cP7!9)EE4JE_CpKNm$ngiQd6xY4JmL^@w4)?=y%5jh4 z!auf7ukMCn8KsG6Yu@eHWuFm~LXtW#Q{`dbQYc&!F{0*9oJ_isRj4^3OW^$n`G{z(Xa44Cyer9IAYb{iROl*G+vS#J`P9!r2(4fcMjs z+ntKX$xu)11m#N(te?|xADoF=?B(7V!g}Wx=#^c@g$6dO`^T;-gUP+XFyL%2AMZ0} zys)48V+NhOXjhH;ddlW88Cgc^4R$$g-P&>wVx!tQy&qC$g>@?Z6`c&Yi(-L$DStSH z)}{#ZWBEz)XKH^@k{lWi5Kgl&?IcVNF$N zZ-1JHPu|;*bX$d#0pyu2&wTEM)!=V{R?9N41@{?ND27HfD;Xd0`X{m_wDU(t&=kUu z-(@~3WLEeLfR+^UAo0APH)o5Jv1OY@GH01Q1j=q3FCP9QNXoLAkpt0#bHhUhrU@LVDBJ`5vU^isj6~$J=1Q)t-CulwtjrwEal@isERv49BXDrbqh2C>5OBq-nya}q9{^hm_4#6@!nfW4TE4t}exs?{e zFy;b_nAON$xh{t-Pb zm-2RdJUNrqoJZms=RaZJR9E;EL`ZIKdH=ZB8PM-?s~`OO!8Nz2?QW+MKU{sRhh*P; z%{$fT=LWE;F+%<3dSqlM_HU6umPZ!!-Gw?)1GAyV2e4&ZS(&HrIW1_}I*r^xn7R6q zQh&1`TX;s-f5-2vZo?9cm$=KT_j`a?19tjne^2-?@ukttHpN_eLo+ZXoboS@N5 zJYPYEYsYPOcSByt>9VT~E5D5Noa)~Be=5OV+V^T`Xy`}1evIxD7J5^cY|&Xq@SFFy5oD^30O50q@y8){!_%ayY=8PRA4=Q5zkJ3_-Hy1hsLvAkk~UK> zoCKc8brK!3u#WBQ6!DOaH9y`75()4jzE-ekRML?lR%EXx8 zZJbOgU%;L^DFL+M64(kpN z)rRGvLKvoPz%nZjM<2X@rsk*wwCRykmM&sy3KcUfnEM0SCn;{kHj1na)2gmIEX#ss zyxTlA{qrbb-+B>)I-1~+gZ&_3mtf^k*46G$R}XfK>1!(wwP&j{_wa>~Cb@+Ss^Y0* zi@25;*e~J#^))!4L-0P)cRyo4o3%`ZwrEvn)zALrkUm-M2p%l@``vmi9?T?=dF_d| zkFr_EXc#T^fhJJ7c&?mO?Xd-5RM8ZI7Cx_ddezF}F9r9!6!s!PDimZT1xl|IbfizR z-rnRNy4sn4Z^G5z9jb)*9F0G|XZBJzE)d)sCH`Bupx3 zJnhX9F?w*Pz%Gn!SjC~gF2$GlSnB39E=`}15+vxTOlL4VN*=k|?VqIJWxO-usviP_Lm6CQa3er-{{PXVHUo6%&*|)Z{Lt7?RVg* ze>fv?m4MEygQk?&3FnKDroZq8Judy{N|ug}Jeh|lJf~X>*o=5PsKRT@R(2rlu*@PXbdw zw;2b6Tbt&2g2Kt%cJC{!s1=5%xs$%RZUQ~JOz6*?anvbOjNT%K9%Nl1{S`LgcP&Z`M5V4Cq!gLKBT>3^m&|>aFw-?_r4{cTWP^)Z%Si zdxwWBInVc`e><(G3!ZNM50W4|Q@00^D|!V|G187jyJbmLL8m*BV+-4l4?i!1L0-1+ z>8+?40)Q#slBj?0R9LZqnZJ7PA%Z@Lmc|%V*7QZRsM7z_zn&yKAtRp;AQ7hapi!v!Otm!aOb$YTCf0_?P!ycNsU zrJm77)3ZGxjh>&IrI^~c_|2uXB78uXIupp5d~R+o}2kzRTk*{ zwIk}|uq_q>%<`Z{2x&?@e?Lcbip{3e6+U4!MRn)N;a5Y<%H(Y8wZT06Y4HWCf4$}n z`-lpEK3DIo=Q9PuR$DwS|8npRKqMUxcf3^jMHsZ$FEQ&A?Yaq=z|7Jl%KZ*&;)hvp z?Eo80@aTgce&R_97ksF2Ih;bbBiE6yGHRIdj|jO<1^V0B3|T(LRBKod7B&IsiG<9T zh(sP>ee-6CG^ySn7C&WdS?gE1hxPGU$60CViB&c?2|;wLlUJupro9JakQy1qtSsS| zra5n0WD%3j2xu3MTKpatUn0ty)#6H>$}5I|Df5k4-n6GZfI2F^cXM2o!5%Ei!#}gtn2;8wUAY(%u*K{#J9gS}2JV z!LEXClsQ|RwL1N(A0%$>y9D?lK+1TCMR~wUdYIO+~LCB=CdIiTd&2 zJLmu^8X!A&N}zQ1(SdRy7S`$;;W##=7&EA;)Dn9bj5l{hH%W5MXUrdTeLPY=8j(t& zzL%B@7?xDcxrg%MN5pi+^Ni{?Gf6UNNx0mVbMMmLOR45f|6ISg8)gGD(Kv8~3SR0z zvZC|#-`^1~Ot6Z?5@~n6d)sr-bey+yrxFfP951SQ7Wcc@`G~bU`&Z*ptn6I zYk1C1d?Hr57DQ;Ysl)9tDuo{S3U|!ZvgA3 z-DLXzwo;oQJT(UHW-0$dtl58@Cd%#RyB(IH@u~|3Jq?}ApMpFSb%x0@iO8ZQ0Po_s ztNQ#Hwfs9Aamf?}2GegwLVeRdF@scruc9@mM5L6pdC`vf4e-!i3f;-%QVb4GY?VCT zTa~H&{@3CrpRt%5l+>nHWi{QIU;Q3Yd?R-^tBQiU!eUK{fBsi4gh&W%GTxS`_Wstk zDiyWK+oI0tpzOwOvPGXnp~k--%#sJ1x&%qp{gmC{$#c>dows9n$6&Srz7f# zu@y&-*rPh85Xuj0E_uIG2 z`{b|6aE!TS%@lM7i9hq{Tj_L~BU}c^VB~Xy5s^_}OoUA7w585TixOw$;&%fyrhd11 zEAh;|!?~VlYF+|P4`~4X8nlmVm=lB7mbIODPNlnED_0EE|vC0E)C^~Rt)vJ2U8uB;m zK>~nOWee2Kj0lplNQZ9*_ExIPO=$CNhlpn@rbZ^53sFuUQsz2ZsaT%{0Tgh~lyg75 z>v3ov7ye!2F9LpS1W{}c%<)Pew%I#KS(P2WbM6N&7m*U$00r`59Mt8-{xm~I5kUsp z5Wu*CxCw`HXs-VsWPELTEHID32336!zt>=aWnTT5X33g&;Aj8vC&aUhYe6*0(Ii_; z@of(F!5N)Go*#lD&k=A!*Vq0 zk6K;zkGaxku4O%+<|DUW8>HT%OlF{M5Go;L1YD{E>*j!9(vWV1DC3=Z7EdtXn2&F z_*&~7XjBqXKbiFc8k=UsMcU)zrE0fLCm52KozD z#{s5Gu)rXdXPQCI?|Zfv!hXD}O?uew@YI9As9M#;Jg?!SRM6oi_R?RMdl`=|#`4L4?BTQ+Nu>{}5;Y{qP!4ZoGsxD@a-rj2g@#1PLe3mamc8t>14pYKK0 z8n;}l`Z}y*TAgqge~q|(O5+up6F(vri%atDssEe+aLK&vfA8^pu$AeW_;~{^Uxydx zaENh6a$VcSk(w?mZ>cJGvGVFw*aWJ<`dj+Qm$JcgEy=^7eEI#yy|E!UP6}Y@xC=(kM+$5Ev;1}V}niombrf_TX z!Zu((z90Pu*ZCi9pPDnx5?^6^m@gJuqOsQ(0xLSFoYcuXdL024VK0xbuGX%{Nelwn z0urCZ5AF<}!OGko4ZY^A%8UxTuMf+Dr4*3_McA#d zo@Rq=N{si=dyom)+7lBh)1rY6{Z`ULbdaxdc!^aCi-j#YO_0R5@+OR8{~Bx+N({Cf z(Xdgb6*-u5@J+3(J@4TNG1PN_z}GXrL}J@GG`zV+MXr3I#tWAiRfP4Qflr`x$#l8XOb`j^Sh32$>H1&i{RVoMhQ#7H`4s zIiM^RSCsu(3T2i(kw9k|bm(DJ`WH~X4UY-5qSEP8Pk&xM?z@+)44NL|L;}NwpT&$z zH2=`akv`7;;J1osKv#u=PC2MZY2y6tn|pd#7GIE5H)mNgMZlk>3KWH66(v0H8@ccO zcg;ZS|@|0^qmbpNw49#h$cV%`%UcQ3;eyQUJXgyuro2+=f--3$@0V zZlfFG??j_&*K!ucm3l#g!e$h4R=+ui3Uv$AFMe;OV=w{N5u)_jppje(k8LfN zbw96U&W&d*t>vQUq7!*Oq&b=;hcFSQCeHkUdlVXhV33`%3|gvoNs6$5BbW7xPg6!j z-zk)}HzkC#oh??)UJNR!TLt}?-DuC;u5m~W!oAcxU5y?LcGdm}%fwjP>b2Ffa7zCT zOHlBy(nwAZSp#Ptc7s)^OxICnvAkyc9+aIJZYC>`bTj9$8ZV?$gl#AqX8FOc(I;8d z&S8lRP1*jxU7QYs7gE$;pIUivz5BG^zwe>PdkJ8aSTr#CCx|OSPc^903sOGJY37$` zBb>F2chCBmLFsYA_beV7MP#JDQc$ghDz|a8*z~JZY)rtx^;#3@e#)xMiSZrQ>{vkh ztW8sfJXva|>AU_2lp?$RNSO+ju@6fI6m1$1c!^k@q8#VyHj{%r9>RzgjSBWlAcpoAm$tXva?2ixO(^d_gh4MvI_vs?-sWD|A6 zZ!gt2HN9C{+fTCoMP8+(q9B;vatbrLA-(46z)x|U6t_-X-suA~m`TOHG(PWJ&>xm( zb?5iBcgz_iA}!}~ky#UI*)Dj@c5G019f?ZhkxZtA-SSdLFdQUW5La0h>j-^;Uf4SJ zT0@N#B}T?y@F3x>blE&>aMVY2N$?mPZmV8DGw5lo_J@-1_%c6+*`z3Ix%F;6)esIA zy^2p7%xMf4i7w6i78d%p{Kni{M1d<{87fARiC;N5#olp`!G_4}!Uod0?q#m}gZIpQDS8Rm#Gb1u_>?NQ@J7`wX9 z#}HLP1^u*s6=GWwsSbD?U%eT8mq(vs%b@3E&PjZLj6*jJkeH-|gPWRdl{nKQ{ z_s2{5hUZAtE}uImGkl{4UeqX(3uRM@y4HyqogSC=mB_rx!kCE7aVBq;UYPvDS_ot9 z1`f#j6b^xPa^EjtslVFUz&6zW@*g-LTHtY5*?VsXhUfP=RDl}9x^?W(;lHA}O8emm z-9Xk^cGH#)^XeZ*N^TzuGkKzi;AV6d%fR!)`?ykwWHAZCkE@e_RKD6LEV)T(R?XP7 z1BQlWiCy={+ML5wQPAj(I9ERmjyMh7i+tYmUMhN|0x`so%$4K94 zz~Fd#PVEUP&>=aIv+mP_+6HADUoc};NE^`Xd7K1_)^c9!k8LO z483F;j&7Iy6pB@jPvgw!7C)O`KRd{f>xevkP-b`-m@2xl%jeds@KMdids5R#?VO^& z`Z2(8N4i-Bjz2#8@h|K^Y;n4cIkj>L~Ms80rkQk#*UYQ)(^27F z%wQP2o=h&MMA#thWc1;e=n#XUu~AB!68PINvfN7U?X(u7;y|!hlg3Ml0KtI&NGS9LUFH3O|H2^<1GFTr7OG{O!@yX1ukf zWW75%`clR4MJAc1^t#SW^QFYm>mH8lmo5&lX9GE;EQ(6N3)A3e zazTI{9CB>gLn!n;t(tHay~i?*&+wQVOK_SMRP%dgc}&#fY7kze2@jd8ydIACFH;2? zEqelMpg0MscP&)JV@gdKA|}Nqi}M9wf;m<`IS>O}R({71C6?))EFAn1{>oH6C|95C zcK5^e2o!*7r|^A%mhF`IA;P-kGs>% zRS>V^KlQUDj&giLB8odaDXT@0<6k34CYU5V=~QV*Yt!$rdF}!7ras3OT^bvp{I;Od z#s~@_r&n?*@M4G0qD61ZgDfk4ebivPPJ-xR_z+@qpu`jQPu;$NIG81zKIE;1)Mfh> z1LzkH3JWc6IVr(RxCyf~howP{6IuhB@Diz?k!6LQi+9uScLuzo?gx`Ri9(EAu~)Y- zDxjaN)p}_Li|apatpl@O^`@Tm-(fq)S&%!gDu494Ssgu$PHO1(U;uEiUxdpo`gG}Y zbSU*vdOy3%Ea&`P5g=0CdP;+fdeXwX0=fHco@l3gEl)B!z@%<~C}rau@rP!2oQ1kZ6z$QMTs`zQ2p;vSf^Be2&wZ?ronH>fg+@hsVDhW3P^(;Z^RlLM! z6Xt45-;EzP$1F;oI=B1T>bw7^nrr`OdjI3f3dtpMq+BLLp;ijz5_74!&RjF0&Jh_V zhY_PRmx#8RyB#d|TuUy?rPMiMMTC*bsHn3^av7aTzVFpv@!gMmykDQ!^ZnZE^?AMb zdcU5p;UO8&x@gq0pgi*Kk1iX3&&eH}$Cn_fu*;yLp}Wzq4UmwS+L?Uv@U8?=RT z?Y5y8T?70c#Kt4=Et%2b+uPFDm^H>wD|7fr!o;_h$c zO{x+z1Se7Rf3}mMU6D!as?^ad7y3=jjXX#6ZUldg-fWFHXHK$Q%+mZADDRD`*VXyB zedwjzkQw&^h-8tgE@=+@1PST55X`7xILEfWkt6v2AvaW81~3N>eA*bSt9$iu&W1AP zx}La}R)!xv{&0S#Y_Fj<@ThC(d%_a%@9OX)PY+h2BJ+1TLLW4^tA>5;16KfnA@=6| zMIo<~*dMM<0*)chDQ;y{X2=r6es?0^1M(JnJi}1z=RM^OY{9LvOkP|b zJkHr@`YqIC0fgI`@FH{SowPFov~G4h5WVKk6oUN+WhCofqJPuCQ8up~D_?K0)5n4Y zTcdrpzVg2P`gcU|_kykvhm)8?8$xxpR76W`@KQ;bWET1EG3+~;4zhOW``@$l1_t_- z3mozNF7oHH49cxd;`7IwRuU9*cE@CXv5sm5Uft(%IT6cB?--BUos4Ghfh|ayDkTy8 zsG90tX2#wsM*TN<{`ko(7GGmw74gHv4)!>yNjR}!OGm{mSP6+bIF&IM=<=7>^^)vv zb_E2+^@>Nf8Z%we&Hmtaq7{&w@u^6}wg7HqtN4EhaK{lh zTTVgl7uGwyH1&Nh7reD-JaOB2J!pHUc=cwa;8+y;9H6C9ie8AZc=bK@*TG>PH5t`-AsXv1fc8a;E9|h?K%u%fMf%>eD1@SjD491#CusenK~<&v9vA|$SFG06bdHaS8H6Fw>c{3`A;W88yqPoRnl3%;Z0-d8kTx2Ugh z>{@b1j_##5$7_}R7EE#23E7xtI2|XPoH2_nO~h8zuUYp+cQuf5Igc9cHx%?iUJ`w4 zI0yQ-Yxoso(rR0wN89tc@yno#2PNwaGRxju5^{y7S5^K!6hS*+?nvPN)`mBvBpGb$DQnLNgGMoSS*LymSwaeAN%Y}b$ zx0Q<-{9IeDm5%w_QGp^I$>lQEcE+S6fb0oX7O#;(iq0#^Lzqf05@Nb(23+5b@Eusc z6B2b5ZA~rzg=-!){goP#qS(dI-}VT1m9zuFS8u9$@Fh5_ujl6+1gZ(R1<}^(j^I$3 zwv;y=-#P}!VXn-eX!2I+;UnwcG%t&66Y`|5$-1e%s|D1=OW`v6WXfp!g2UHGngZ+d zeo^qxu2J{%bRq>vBMod6`vYSse#j8SCDcK@hP*WM&aa`cZh8OZs!-y5OVc<8?svXE z%Yk;0dZ6q_MnIL#`#V)dT`2E1BRjJ?SbY)6oLLis{AD0TB5%*E?0L`1F~KS!Z#p;C zBmY~5vakJHtu&gucx4W0zoM4PEOjnbFlELqwy^-wDXRrxX$Zh!b61r{#lziyHH%HR zfW0!#Dtrb1Qxp%~=A_zCd-Z<5zDy1r{Nkxj@xbt&_G4U&xvLK9xV7>KiLzc05YLk7 zvAZV&(w;nDG7NNscc3)wENgUL8pbqU^d*3IvW`)W3Sd8CW!=b!d%H2}3~A(;kJ;LY zv>G~DPza3erb5KpdqwX&O=rO+gZ9ies5vyQC2~Vv-nepKJ@ZxRWud#oK&zv!-uSeH z%^vgmRB>5<+|eJtk{Nw$YMd8_wB9@kmZX6t*%7DvL|$0xXX7j~IEqw-7xKI+fYDA8 z(IU3lEztR-l2q}Ozo4_5B7rbwB)1s&CjMDIr@EKr!2#o8z6b*$TaJh&3+A9+>$<9T z8yC|10;@YzQ3y@dL5Zb>;>e?=ZvkfdTUj?krPuu7FH@x%1Vy#G0~o@QRW9oO>(FW# zg%mKYorV`&O58=CGRrS(F+#;}xq_6IFl^;qlxbRdjC3*Y6xOL{@bO=(%d%4CTX4sc zOO@+~yJnbXx?N=4+0ImMDuBWQZHrc$b@($@mZZE9E<57 zuxDlhy&bwOHz~s|5i7-T96A(wTun1KEcLy1$Qd%#dDMpIt-CA&H?@qFGR!Jzg zNA7(Bx6~DHu)n8?4wb@>0N`1Y2)u>tg*<5@z#@W#R!ciK6=cRrWhX-4YHg zGtLnzDF`ES7h^>UTM6tr1BI|Omsndr<|p^|>fT&?)X?M;fsUAjjFgnpfI<=Fod`UW zeiBBo^(bU$qML8Z3A5|I9Ymho0sltFeb-V%Rg+u}9(mvAUr`dDQYX}uA&S7;#POeO zEuXl}-M#(u1I-T;WkI+fvwn}agritQ&RaP9AmH0WuykwxYM6$K<47oE7<@kijDLGX zZci=)aZqaIiBzElMnh%K)R*vjgmVVZZz=RxqHvN&BP)P2CPGX8t-2J^D%++( z&Ar;39wO8~yA8olvOh7=L?AGliBPlwy;aPei74hm}4Ug9780=%2}!r*?!yE zw8Z~mRz~Zn<5vv)Pto##5`$|2RPDl>zvUWkzXBGD?;v9Ld121zN9#y29^ou~R?woj z;_*Q~q5l*A>AG60t&8Yv{B#+A;G>NB>%l+9`Xfe3{H+3q8NE=*EAW8-^UpD_A8NrO VDCRS=dWdi6D3^r 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 literal 0 HcmV?d00001 From 8bb7023db7e4e3843e05d86b7fa7e2e50cee98fe Mon Sep 17 00:00:00 2001 From: Jeroen van den Hout Date: Mon, 10 Jun 2024 22:40:15 +0200 Subject: [PATCH 13/37] fix(docs): apply correct file extensions --- .../_partials/_oracles_contract_data.mdx | 37 +++++++++++++++++++ .../{invocation.md => invocation.mdx} | 0 ...uages-and-vms.md => languages-and-vms.mdx} | 0 .../how-tos/{ERC20.md => ERC20.mdx} | 0 .../how-tos/{ERC721.md => ERC721.mdx} | 0 .../nft/{introduction.md => introduction.mdx} | 0 .../nft/{mint-nft.md => mint-nft.mdx} | 0 .../{create-foundry.md => create-foundry.mdx} | 0 ...ative-token.md => create-native-token.mdx} | 0 .../{introduction.md => introduction.mdx} | 0 .../token/{mint-token.md => mint-token.mdx} | 0 .../{register-token.md => register-token.mdx} | 0 ...ontract.md => create-a-basic-contract.mdx} | 0 .../{introduction.md => introduction.mdx} | 0 ...ess-node.md => running-an-access-node.mdx} | 0 15 files changed, 37 insertions(+) create mode 100644 docs/content/guides/developer/iota-chains/_partials/_oracles_contract_data.mdx rename docs/content/guides/developer/iota-chains/explanations/{invocation.md => invocation.mdx} (100%) rename docs/content/guides/developer/iota-chains/getting-started/{languages-and-vms.md => languages-and-vms.mdx} (100%) rename docs/content/guides/developer/iota-chains/how-tos/{ERC20.md => ERC20.mdx} (100%) rename docs/content/guides/developer/iota-chains/how-tos/{ERC721.md => ERC721.mdx} (100%) rename docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/{introduction.md => introduction.mdx} (100%) rename docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/{mint-nft.md => mint-nft.mdx} (100%) rename docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/{create-foundry.md => create-foundry.mdx} (100%) rename docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/{create-native-token.md => create-native-token.mdx} (100%) rename docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/{introduction.md => introduction.mdx} (100%) rename docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/{mint-token.md => mint-token.mdx} (100%) rename docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/{register-token.md => register-token.mdx} (100%) rename docs/content/guides/developer/iota-chains/how-tos/{create-a-basic-contract.md => create-a-basic-contract.mdx} (100%) rename docs/content/guides/developer/iota-chains/{introduction.md => introduction.mdx} (100%) rename docs/content/guides/operator/iota-chains-node/how-tos/{running-an-access-node.md => running-an-access-node.mdx} (100%) diff --git a/docs/content/guides/developer/iota-chains/_partials/_oracles_contract_data.mdx b/docs/content/guides/developer/iota-chains/_partials/_oracles_contract_data.mdx new file mode 100644 index 00000000000..2c0183b08e1 --- /dev/null +++ b/docs/content/guides/developer/iota-chains/_partials/_oracles_contract_data.mdx @@ -0,0 +1,37 @@ +import { AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; +import { Networks } from '@theme/constant'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + + + +| Contract Type | Contract Address | +|:----------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------:| +| Pyth contract | [https://explorer.evm.iota.org/address/0x8D254a21b3C86D32F7179855531CE99164721933](https://explorer.evm.iota.org/address/0x8D254a21b3C86D32F7179855531CE99164721933) | +| Supra Pull Contract | [https://explorer.evm.iota.org/address/0x2FA6DbFe4291136Cf272E1A3294362b6651e8517](https://explorer.evm.iota.org/address/0x2FA6DbFe4291136Cf272E1A3294362b6651e8517) | +| Supra Storage Contract | [https://explorer.evm.iota.org/address/0xD02cc7a670047b6b012556A88e275c685d25e0c9](https://explorer.evm.iota.org/address/0xD02cc7a670047b6b012556A88e275c685d25e0c9) | +| Supra Push Contract | [https://explorer.evm.iota.org/address/0xD02cc7a670047b6b012556A88e275c685d25e0c9](https://explorer.evm.iota.org/address/0xD02cc7a670047b6b012556A88e275c685d25e0c9) | + + + + +| Contract Type | Contract Address | +|:----------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------:| +| Pyth contract | [https://explorer.evm.shimmer.network/address/0x290f23E4a034Db5237edCb5aA2D94Acb4DD19fD2](https://explorer.evm.shimmer.network/address/0x290f23E4a034Db5237edCb5aA2D94Acb4DD19fD2) | +| Supra Pull Contract | [https://explorer.evm.shimmer.network/address/0xe41444462709484272F54371F3f53bBF900Ec49E](https://explorer.evm.shimmer.network/address/0xe41444462709484272F54371F3f53bBF900Ec49E) | +| Supra Storage Contract | [https://explorer.evm.shimmer.network/address/0x3E5E89d14576cE9f20a8347aA682517fe65B4ACB](https://explorer.evm.shimmer.network/address/0x3E5E89d14576cE9f20a8347aA682517fe65B4ACB) | +| Supra Push Contract | [https://explorer.evm.shimmer.network/address/0x3df842b27c997cEc63160E79CB4398c82645A1c3](https://explorer.evm.shimmer.network/address/0x3df842b27c997cEc63160E79CB4398c82645A1c3) | + + + + +:::tip Oracle Documentation + +You can find detailed documentation on the Oracles in their official documentation: + +* [Pyth Oracle Docs](https://docs.pyth.network/price-feeds/contract-addresses/evm) +* [Supra Pull Docs](https://gb-docs.supraoracles.com/docs/data-feeds/pull-model/networks) +* [Supra Push Docs](https://gb-docs.supraoracles.com/docs/data-feeds/decentralized/networks) + +::: diff --git a/docs/content/guides/developer/iota-chains/explanations/invocation.md b/docs/content/guides/developer/iota-chains/explanations/invocation.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/explanations/invocation.md rename to docs/content/guides/developer/iota-chains/explanations/invocation.mdx diff --git a/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.md b/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.md rename to docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.mdx diff --git a/docs/content/guides/developer/iota-chains/how-tos/ERC20.md b/docs/content/guides/developer/iota-chains/how-tos/ERC20.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/ERC20.md rename to docs/content/guides/developer/iota-chains/how-tos/ERC20.mdx diff --git a/docs/content/guides/developer/iota-chains/how-tos/ERC721.md b/docs/content/guides/developer/iota-chains/how-tos/ERC721.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/ERC721.md rename to docs/content/guides/developer/iota-chains/how-tos/ERC721.mdx diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/introduction.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/introduction.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/introduction.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/introduction.mdx diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.mdx diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/introduction.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/introduction.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/introduction.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/introduction.mdx diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.mdx diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/register-token.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/register-token.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/register-token.md rename to docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/register-token.mdx diff --git a/docs/content/guides/developer/iota-chains/how-tos/create-a-basic-contract.md b/docs/content/guides/developer/iota-chains/how-tos/create-a-basic-contract.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/create-a-basic-contract.md rename to docs/content/guides/developer/iota-chains/how-tos/create-a-basic-contract.mdx diff --git a/docs/content/guides/developer/iota-chains/introduction.md b/docs/content/guides/developer/iota-chains/introduction.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/introduction.md rename to docs/content/guides/developer/iota-chains/introduction.mdx diff --git a/docs/content/guides/operator/iota-chains-node/how-tos/running-an-access-node.md b/docs/content/guides/operator/iota-chains-node/how-tos/running-an-access-node.mdx similarity index 100% rename from docs/content/guides/operator/iota-chains-node/how-tos/running-an-access-node.md rename to docs/content/guides/operator/iota-chains-node/how-tos/running-an-access-node.mdx From ae7d5cdf880617865cc1862ec58fb4738441b52c Mon Sep 17 00:00:00 2001 From: Jeroen van den Hout Date: Mon, 10 Jun 2024 22:16:26 +0200 Subject: [PATCH 14/37] fix(docs): add missing partials and fix paths --- .../_partials/_metamask_buttons.mdx | 19 +++++++++++++++++++ .../explanations/how-accounts-work.md | 2 +- .../explanations/smart-contract-anatomy.md | 2 +- .../getting-started/quick-start.mdx | 2 +- .../iota-chains/getting-started/tools.mdx | 6 +++--- .../core-contracts/nft/introduction.mdx | 2 +- .../how-tos/core-contracts/nft/mint-nft.mdx | 2 +- .../core-contracts/token/create-foundry.mdx | 2 +- .../token/create-native-token.mdx | 2 +- .../core-contracts/token/introduction.mdx | 4 ++-- .../core-contracts/token/mint-token.mdx | 4 ++-- .../core-contracts/token/register-token.mdx | 2 +- .../how-tos/deploy-a-smart-contract.mdx | 10 +++++----- .../how-tos/send-funds-from-L1-to-L2.mdx | 2 +- .../developer/iota-chains/introduction.mdx | 4 ++-- .../iota-chains/solo/how-tos/deploying-sc.md | 2 +- 16 files changed, 43 insertions(+), 24 deletions(-) create mode 100644 docs/content/guides/developer/iota-chains/_partials/_metamask_buttons.mdx diff --git a/docs/content/guides/developer/iota-chains/_partials/_metamask_buttons.mdx b/docs/content/guides/developer/iota-chains/_partials/_metamask_buttons.mdx new file mode 100644 index 00000000000..f4f28683502 --- /dev/null +++ b/docs/content/guides/developer/iota-chains/_partials/_metamask_buttons.mdx @@ -0,0 +1,19 @@ +import { AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; +import { Networks } from '@theme/constant'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/content/guides/developer/iota-chains/explanations/how-accounts-work.md b/docs/content/guides/developer/iota-chains/explanations/how-accounts-work.md index 15809f5d2dd..348455d1cf7 100644 --- a/docs/content/guides/developer/iota-chains/explanations/how-accounts-work.md +++ b/docs/content/guides/developer/iota-chains/explanations/how-accounts-work.md @@ -66,7 +66,7 @@ The Agent ID of the common account is `@

`. ### Ethereum Address -An L2 account can also be owned by an Ethereum address. See [EVM](../introduction.md) for more information. +An L2 account can also be owned by an Ethereum address. See [EVM](../introduction.mdx) for more information. The Agent ID of an Ethereum address is just the address prefixed with `0x`, e.g. `0xd36722adec3edcb29c8e7b5a47f352d701393462`. diff --git a/docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md b/docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md index db01895d106..76a3c1b96ec 100644 --- a/docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md +++ b/docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md @@ -16,7 +16,7 @@ Smart contracts are programs that are immutably stored in the chain. Through _VM abstraction_, the ISC virtual machine is agnostic about the interpreter used to execute each smart contract. It can support different _VM types_ (i.e., interpreters) simultaneously on the same chain. -For example, it is possible to have [Wasm](../getting-started/languages-and-vms.md#wasm-vm-for-isc) and [EVM/Solidity](../getting-started/languages-and-vms.md#evmsolidity-based-smart-contracts) smart +For example, it is possible to have [Wasm](../getting-started/languages-and-vms.mdxwasm-vm-for-isc) and [EVM/Solidity](../getting-started/languages-and-vms.mdxevmsolidity-based-smart-contracts) smart contracts coexisting on the same chain. ![Smart Contract Structure](/img/iota-chains/tutorial/SC-structure.png) diff --git a/docs/content/guides/developer/iota-chains/getting-started/quick-start.mdx b/docs/content/guides/developer/iota-chains/getting-started/quick-start.mdx index 65b242366db..42e2a6be7ed 100644 --- a/docs/content/guides/developer/iota-chains/getting-started/quick-start.mdx +++ b/docs/content/guides/developer/iota-chains/getting-started/quick-start.mdx @@ -13,7 +13,7 @@ tags: - RPC --- import DeployAdmonition from '../_admonitions/_deploy_a_smart_contract.md'; -import MetamaskButtons from '../../../../_partials/_metamask_buttons.mdx'; +import MetamaskButtons from '../_partials/_metamask_buttons.mdx'; import { Networks } from '@theme/constant'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; diff --git a/docs/content/guides/developer/iota-chains/getting-started/tools.mdx b/docs/content/guides/developer/iota-chains/getting-started/tools.mdx index 9f599ff7c09..633a16ee258 100644 --- a/docs/content/guides/developer/iota-chains/getting-started/tools.mdx +++ b/docs/content/guides/developer/iota-chains/getting-started/tools.mdx @@ -19,12 +19,12 @@ tags: import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import {AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; -import HardhatConfig from '../_partials/_hardhat_config.md'; +import HardhatConfig from '../_partials/_hardhat_config.mdx'; import { Networks } from '@theme/constant'; import DeployAdmonition from '../_admonitions/_deploy_a_smart_contract.md'; import { ChainId } from '@theme/ChainId'; import NetworkInfo from '@theme/NetworkInfo'; -import OraclesContractData from '../../../../_partials/_oracles_contract_data.md'; +import OraclesContractData from '../_partials/_oracles_contract_data.mdx'; # Compatible Tools @@ -81,7 +81,7 @@ for accessing blockchain data. You can find the Blast API URLs in the [Network R ### EVM Toolkit You can use the [IOTA EVM Toolkit](https://evm-toolkit.evm.iotaledger.net) to withdraw assets from IOTA EVM to IOTA L1. -It also includes a wrapper IOTA <-> wIOTA. +It also includes a wrapper wIOTA, which wraps IOTA. ### Multicall3 diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/introduction.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/introduction.mdx index 506f0dfef13..d20e79504e0 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/introduction.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/introduction.mdx @@ -12,6 +12,6 @@ import DocCardList from '@theme/DocCardList'; # Native NFT and ERC721 The IOTA L1 can create NFTs, also called native NFTs. To use these NFTs on L2, you have -an ERC20 contract called `ERC721NFTs`, which contains all L1 NFTs owned by the chain. The following guides will show you how to [mint your own L1 NFT from L2](./mint-nft.md) and [use](./use-as-erc721.md) it with the `ERC721NFTs` contract. +an ERC20 contract called `ERC721NFTs`, which contains all L1 NFTs owned by the chain. The following guides will show you how to [mint your own L1 NFT from L2](./mint-nft.mdx and [use](./use-as-ERC721.mdx it with the `ERC721NFTs` contract. \ No newline at end of file diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx index d889d7972a2..f0fae55b102 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx @@ -6,7 +6,7 @@ tags: - EVM - how-to --- -import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.md'; +import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.mdx'; # Mint an NFT ## About NFTs diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.mdx index 17ba120d40c..82e3f770c26 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.mdx @@ -6,7 +6,7 @@ tags: - EVM - how-to --- -import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.md'; +import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.mdx'; import ObsoleteTokenCreation from '../../../_partials/how-tos/token/_obsolete_token_creation.md'; # Create a Foundry diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx index 06baa4615d1..84ed2433e4c 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx @@ -10,7 +10,7 @@ tags: - register --- -import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.md'; +import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.mdx'; # Create a Native Token diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/introduction.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/introduction.mdx index 83fb4021e47..5c86f899bf1 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/introduction.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/introduction.mdx @@ -11,8 +11,8 @@ import DocCardList from '@theme/DocCardList'; # Native Token and ERC20NativeToken The IOTA L1 has functionality to create L1 tokens, also called native tokens. To use these native tokens on L2, you have -a ERC20 contract called `ERC20NativeToken`. The following guides will show you how to [create a foundry](create-foundry.md) -that can [mint your own L1 token from L2](mint-token.md), and [register](register-token.md) it as `ERC20NativeToken`, +a ERC20 contract called `ERC20NativeToken`. The following guides will show you how to [create a foundry](create-foundry.mdx +that can [mint your own L1 token from L2](mint-token.mdx, and [register](register-token.mdx it as `ERC20NativeToken`, so it can be used like any other ERC20 token with some additional features. \ No newline at end of file diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.mdx index bd79533d844..56918a7e83f 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.mdx @@ -8,11 +8,11 @@ tags: - native tokens - mint --- -import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.md'; +import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.mdx'; # Mint Native Tokens -To mint tokens from a [foundry](/tips/tips/TIP-0018/#foundry-output), you first need to be aware that only the foundry owner can mint token, so you should execute the `ISC.accounts.mintNativeTokens` function in the same contract where you also [created the native token](./create-native-token.md). +To mint tokens from a [foundry](/tips/tips/TIP-0018/#foundry-output), you first need to be aware that only the foundry owner can mint token, so you should execute the `ISC.accounts.mintNativeTokens` function in the same contract where you also [created the native token](./create-native-token.mdx. ## Example Code diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/register-token.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/register-token.mdx index 990ae5e69b3..a97a64b88c7 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/register-token.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/register-token.mdx @@ -6,7 +6,7 @@ tags: - EVM - how-to --- -import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.md'; +import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.mdx'; import ObsoleteTokenCreation from '../../../_partials/how-tos/token/_obsolete_token_creation.md'; # Register Tokens diff --git a/docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx b/docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx index ca9ab2d3d9d..efb531f634d 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx @@ -10,8 +10,8 @@ image: /img/logo/WASP_logo_dark.png description: 'Learn how to deploy smart contracts to IOTA EVM, Shimmer EVM and EVM Testnet using popular tools like Remix and Hardhat.' --- import {AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; -import HardhatConfig from '../_partials/_hardhat_config.md'; -import MetamaskButtons from '../../../../_partials/_metamask_buttons.mdx'; +import HardhatConfig from '../_partials/_hardhat_config.mdx'; +import MetamaskButtons from '../_partials/_metamask_buttons.mdx'; import { Networks } from '@theme/constant'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; @@ -24,7 +24,7 @@ and [Hardhat](#hardhat). :::tip Get a Basic Contract This guide will deploy the `Counter` contract you can find in -the [How to Create a Basic Solidity Contract Guide](create-a-basic-contract.md). +the [How to Create a Basic Solidity Contract Guide](create-a-basic-contract.mdx. ::: @@ -55,7 +55,7 @@ Open your web browser and navigate to [Remix IDE](https://remix.ethereum.org/). 1. In the `File Explorer` tab on the left, click the `Create New File` icon. 2. Name your file `Counter.sol`. -3. Copy the Solidity code for the [basic counter smart contract](create-a-basic-contract.md) and paste it into +3. Copy the Solidity code for the [basic counter smart contract](create-a-basic-contract.mdx and paste it into the `Counter.sol` file you just created in Remix. ### 4. Compile Your Smart Contract @@ -119,7 +119,7 @@ project. Here's a step-by-step guide: ### 2. Add Your Contract 1. Inside the `contracts` folder, create a new file called `Counter.sol` and paste the content of - the [Counter Basic Contract](create-a-basic-contract.md). + the [Counter Basic Contract](create-a-basic-contract.mdx. ### 3. Create a Deployment Script diff --git a/docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx b/docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx index 03d90948280..79fbec5304d 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx @@ -17,7 +17,7 @@ tags: import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import {AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; -import MetamaskButtons from '../../../../_partials/_metamask_buttons.mdx'; +import MetamaskButtons from '../_partials/_metamask_buttons.mdx'; import { Networks } from '@theme/constant'; # Send Funds From L1 to L2 diff --git a/docs/content/guides/developer/iota-chains/introduction.mdx b/docs/content/guides/developer/iota-chains/introduction.mdx index 28b9d0a7bd7..a82632b7e1c 100644 --- a/docs/content/guides/developer/iota-chains/introduction.mdx +++ b/docs/content/guides/developer/iota-chains/introduction.mdx @@ -46,8 +46,8 @@ _IOTA Smart Contacts multichain architecture._ ## Supported VMs The IOTA Smart Contracts currently -supports [EVM/Solidity](getting-started/languages-and-vms.md#evmsolidity-based-smart-contracts) -smart contracts, as well as an **experimental** [Wasm VM](getting-started/languages-and-vms.md#wasm-vm-for-isc). +supports [EVM/Solidity](getting-started/languages-and-vms.mdxevmsolidity-based-smart-contracts) +smart contracts, as well as an **experimental** [Wasm VM](getting-started/languages-and-vms.mdxwasm-vm-for-isc). ## Sandbox Interface diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/deploying-sc.md b/docs/content/guides/developer/iota-chains/solo/how-tos/deploying-sc.md index 33534aae023..18088e855c1 100644 --- a/docs/content/guides/developer/iota-chains/solo/how-tos/deploying-sc.md +++ b/docs/content/guides/developer/iota-chains/solo/how-tos/deploying-sc.md @@ -18,7 +18,7 @@ tags: :::note WASM VM -For more information about how to create Wasm smart contracts, refer to the [Wasm VM chapter](../../getting-started/languages-and-vms.md#wasm-vm-for-isc). +For more information about how to create Wasm smart contracts, refer to the [Wasm VM chapter](../../getting-started/languages-and-vms.mdxwasm-vm-for-isc). ::: From 29840caf43c5484dd0de5b31f506ea7018917a82 Mon Sep 17 00:00:00 2001 From: Jeroen van den Hout Date: Mon, 10 Jun 2024 22:47:38 +0200 Subject: [PATCH 15/37] fix(docs): add missing frontmatter --- .../getting-started/languages-and-vms.mdx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.mdx b/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.mdx index 16fcd5fba36..558c70a948d 100644 --- a/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.mdx +++ b/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.mdx @@ -1,3 +1,16 @@ +--- +description: Compatibility between languages and different virtual machines. +image: /img/logo/WASP_logo_dark.png +tags: + - smart contracts + - EVM + - Ethereum + - Solidity + - limitations + - compatibility + - reference +--- + import EVMCompatibility from '../_admonitions/_EVM_compatibility.md' # Supported Virtual Machines & Languages From 9b3905e5d2c5bd026cc2550389cb301294a8f362 Mon Sep 17 00:00:00 2001 From: Jeroen van den Hout Date: Mon, 10 Jun 2024 23:26:08 +0200 Subject: [PATCH 16/37] refactor(docs): move admonitions and partials to snippets --- .../iota-chains/EVM-required-prior-knowledge.md} | 0 .../iota-chains/EVM_compatibility.md} | 0 .../iota-chains/about-accounts.md} | 0 .../iota-chains/deploy_a_smart_contract.md} | 0 .../iota-chains/hardhat_config.mdx} | 0 .../iota-chains/how-tos/token/check_storage_deposit.md} | 0 .../iota-chains/how-tos/token/example_code_intro.mdx | 9 +++++++++ .../how-tos/token/obsolete_token_creation.md} | 0 .../iota-chains/metamask_buttons.mdx} | 0 .../iota-chains/on_off_ledger_request.md} | 0 .../iota-chains/oracles_contract_data.mdx} | 0 .../_ownership.md => _snippets/iota-chains/ownership.md} | 0 .../_payable.md => _snippets/iota-chains/payable.md} | 0 .../_remix-IDE.md => _snippets/iota-chains/remix-IDE.md} | 0 .../_partials/how-tos/token/_example_code_intro.mdx | 9 --------- .../developer/iota-chains/explanations/invocation.mdx | 2 +- .../iota-chains/getting-started/languages-and-vms.mdx | 2 +- .../iota-chains/getting-started/quick-start.mdx | 4 ++-- .../developer/iota-chains/getting-started/tools.mdx | 6 +++--- .../guides/developer/iota-chains/how-tos/ERC20.mdx | 6 +++--- .../guides/developer/iota-chains/how-tos/ERC721.mdx | 6 +++--- .../how-tos/core-contracts/basics/send-assets-to-l1.mdx | 2 +- .../iota-chains/how-tos/core-contracts/nft/mint-nft.mdx | 2 +- .../how-tos/core-contracts/token/create-foundry.mdx | 4 ++-- .../how-tos/core-contracts/token/create-native-token.mdx | 2 +- .../how-tos/core-contracts/token/mint-token.mdx | 2 +- .../how-tos/core-contracts/token/register-token.mdx | 4 ++-- .../iota-chains/how-tos/create-a-basic-contract.mdx | 2 +- .../iota-chains/how-tos/deploy-a-smart-contract.mdx | 4 ++-- .../iota-chains/how-tos/send-funds-from-L1-to-L2.mdx | 2 +- .../guides/developer/iota-chains/introduction.mdx | 2 +- 31 files changed, 35 insertions(+), 35 deletions(-) rename docs/content/{guides/developer/iota-chains/_admonitions/_EVM-required-prior-knowledge.md => _snippets/iota-chains/EVM-required-prior-knowledge.md} (100%) rename docs/content/{guides/developer/iota-chains/_admonitions/_EVM_compatibility.md => _snippets/iota-chains/EVM_compatibility.md} (100%) rename docs/content/{guides/developer/iota-chains/_admonitions/_about-accounts.md => _snippets/iota-chains/about-accounts.md} (100%) rename docs/content/{guides/developer/iota-chains/_admonitions/_deploy_a_smart_contract.md => _snippets/iota-chains/deploy_a_smart_contract.md} (100%) rename docs/content/{guides/developer/iota-chains/_partials/_hardhat_config.mdx => _snippets/iota-chains/hardhat_config.mdx} (100%) rename docs/content/{guides/developer/iota-chains/_partials/how-tos/token/_check_storage_deposit.md => _snippets/iota-chains/how-tos/token/check_storage_deposit.md} (100%) create mode 100644 docs/content/_snippets/iota-chains/how-tos/token/example_code_intro.mdx rename docs/content/{guides/developer/iota-chains/_partials/how-tos/token/_obsolete_token_creation.md => _snippets/iota-chains/how-tos/token/obsolete_token_creation.md} (100%) rename docs/content/{guides/developer/iota-chains/_partials/_metamask_buttons.mdx => _snippets/iota-chains/metamask_buttons.mdx} (100%) rename docs/content/{guides/developer/iota-chains/_partials/_on_off_ledger_request.md => _snippets/iota-chains/on_off_ledger_request.md} (100%) rename docs/content/{guides/developer/iota-chains/_partials/_oracles_contract_data.mdx => _snippets/iota-chains/oracles_contract_data.mdx} (100%) rename docs/content/{guides/developer/iota-chains/_admonitions/_ownership.md => _snippets/iota-chains/ownership.md} (100%) rename docs/content/{guides/developer/iota-chains/_admonitions/_payable.md => _snippets/iota-chains/payable.md} (100%) rename docs/content/{guides/developer/iota-chains/_admonitions/_remix-IDE.md => _snippets/iota-chains/remix-IDE.md} (100%) delete mode 100644 docs/content/guides/developer/iota-chains/_partials/how-tos/token/_example_code_intro.mdx diff --git a/docs/content/guides/developer/iota-chains/_admonitions/_EVM-required-prior-knowledge.md b/docs/content/_snippets/iota-chains/EVM-required-prior-knowledge.md similarity index 100% rename from docs/content/guides/developer/iota-chains/_admonitions/_EVM-required-prior-knowledge.md rename to docs/content/_snippets/iota-chains/EVM-required-prior-knowledge.md diff --git a/docs/content/guides/developer/iota-chains/_admonitions/_EVM_compatibility.md b/docs/content/_snippets/iota-chains/EVM_compatibility.md similarity index 100% rename from docs/content/guides/developer/iota-chains/_admonitions/_EVM_compatibility.md rename to docs/content/_snippets/iota-chains/EVM_compatibility.md diff --git a/docs/content/guides/developer/iota-chains/_admonitions/_about-accounts.md b/docs/content/_snippets/iota-chains/about-accounts.md similarity index 100% rename from docs/content/guides/developer/iota-chains/_admonitions/_about-accounts.md rename to docs/content/_snippets/iota-chains/about-accounts.md diff --git a/docs/content/guides/developer/iota-chains/_admonitions/_deploy_a_smart_contract.md b/docs/content/_snippets/iota-chains/deploy_a_smart_contract.md similarity index 100% rename from docs/content/guides/developer/iota-chains/_admonitions/_deploy_a_smart_contract.md rename to docs/content/_snippets/iota-chains/deploy_a_smart_contract.md diff --git a/docs/content/guides/developer/iota-chains/_partials/_hardhat_config.mdx b/docs/content/_snippets/iota-chains/hardhat_config.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/_partials/_hardhat_config.mdx rename to docs/content/_snippets/iota-chains/hardhat_config.mdx diff --git a/docs/content/guides/developer/iota-chains/_partials/how-tos/token/_check_storage_deposit.md b/docs/content/_snippets/iota-chains/how-tos/token/check_storage_deposit.md similarity index 100% rename from docs/content/guides/developer/iota-chains/_partials/how-tos/token/_check_storage_deposit.md rename to docs/content/_snippets/iota-chains/how-tos/token/check_storage_deposit.md diff --git a/docs/content/_snippets/iota-chains/how-tos/token/example_code_intro.mdx b/docs/content/_snippets/iota-chains/how-tos/token/example_code_intro.mdx new file mode 100644 index 00000000000..cdd6b4a7b94 --- /dev/null +++ b/docs/content/_snippets/iota-chains/how-tos/token/example_code_intro.mdx @@ -0,0 +1,9 @@ +import Ownership from '../../ownership.md'; +import Payable from '../../payable.md'; +import CheckStorageDeposit from './check_storage_deposit.md' + + + + + + diff --git a/docs/content/guides/developer/iota-chains/_partials/how-tos/token/_obsolete_token_creation.md b/docs/content/_snippets/iota-chains/how-tos/token/obsolete_token_creation.md similarity index 100% rename from docs/content/guides/developer/iota-chains/_partials/how-tos/token/_obsolete_token_creation.md rename to docs/content/_snippets/iota-chains/how-tos/token/obsolete_token_creation.md diff --git a/docs/content/guides/developer/iota-chains/_partials/_metamask_buttons.mdx b/docs/content/_snippets/iota-chains/metamask_buttons.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/_partials/_metamask_buttons.mdx rename to docs/content/_snippets/iota-chains/metamask_buttons.mdx diff --git a/docs/content/guides/developer/iota-chains/_partials/_on_off_ledger_request.md b/docs/content/_snippets/iota-chains/on_off_ledger_request.md similarity index 100% rename from docs/content/guides/developer/iota-chains/_partials/_on_off_ledger_request.md rename to docs/content/_snippets/iota-chains/on_off_ledger_request.md diff --git a/docs/content/guides/developer/iota-chains/_partials/_oracles_contract_data.mdx b/docs/content/_snippets/iota-chains/oracles_contract_data.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/_partials/_oracles_contract_data.mdx rename to docs/content/_snippets/iota-chains/oracles_contract_data.mdx diff --git a/docs/content/guides/developer/iota-chains/_admonitions/_ownership.md b/docs/content/_snippets/iota-chains/ownership.md similarity index 100% rename from docs/content/guides/developer/iota-chains/_admonitions/_ownership.md rename to docs/content/_snippets/iota-chains/ownership.md diff --git a/docs/content/guides/developer/iota-chains/_admonitions/_payable.md b/docs/content/_snippets/iota-chains/payable.md similarity index 100% rename from docs/content/guides/developer/iota-chains/_admonitions/_payable.md rename to docs/content/_snippets/iota-chains/payable.md diff --git a/docs/content/guides/developer/iota-chains/_admonitions/_remix-IDE.md b/docs/content/_snippets/iota-chains/remix-IDE.md similarity index 100% rename from docs/content/guides/developer/iota-chains/_admonitions/_remix-IDE.md rename to docs/content/_snippets/iota-chains/remix-IDE.md diff --git a/docs/content/guides/developer/iota-chains/_partials/how-tos/token/_example_code_intro.mdx b/docs/content/guides/developer/iota-chains/_partials/how-tos/token/_example_code_intro.mdx deleted file mode 100644 index daf06c0839b..00000000000 --- a/docs/content/guides/developer/iota-chains/_partials/how-tos/token/_example_code_intro.mdx +++ /dev/null @@ -1,9 +0,0 @@ -import Ownership from '../../../_admonitions/_ownership.md'; -import Payable from '../../../_admonitions/_payable.md'; -import CheckStorageDeposit from './_check_storage_deposit.md' - - - - - - diff --git a/docs/content/guides/developer/iota-chains/explanations/invocation.mdx b/docs/content/guides/developer/iota-chains/explanations/invocation.mdx index 28756fd0713..20f7c54c9d3 100644 --- a/docs/content/guides/developer/iota-chains/explanations/invocation.mdx +++ b/docs/content/guides/developer/iota-chains/explanations/invocation.mdx @@ -14,7 +14,7 @@ tags: --- -import OnOffLedgerRequest from '../_partials/_on_off_ledger_request.md'; +import OnOffLedgerRequest from '../../../../_snippets/iota-chains/on_off_ledger_request.md'; # Calling a Smart Contract diff --git a/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.mdx b/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.mdx index 558c70a948d..e5f2f7a5303 100644 --- a/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.mdx +++ b/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.mdx @@ -11,7 +11,7 @@ tags: - reference --- -import EVMCompatibility from '../_admonitions/_EVM_compatibility.md' +import EVMCompatibility from '../../../../_snippets/iota-chains/EVM_compatibility.md' # Supported Virtual Machines & Languages diff --git a/docs/content/guides/developer/iota-chains/getting-started/quick-start.mdx b/docs/content/guides/developer/iota-chains/getting-started/quick-start.mdx index 42e2a6be7ed..ac206942f93 100644 --- a/docs/content/guides/developer/iota-chains/getting-started/quick-start.mdx +++ b/docs/content/guides/developer/iota-chains/getting-started/quick-start.mdx @@ -12,8 +12,8 @@ tags: - JSON - RPC --- -import DeployAdmonition from '../_admonitions/_deploy_a_smart_contract.md'; -import MetamaskButtons from '../_partials/_metamask_buttons.mdx'; +import DeployAdmonition from '../../../../_snippets/iota-chains/deploy_a_smart_contract.md'; +import MetamaskButtons from '../../../../_snippets/iota-chains/metamask_buttons.mdx'; import { Networks } from '@theme/constant'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; diff --git a/docs/content/guides/developer/iota-chains/getting-started/tools.mdx b/docs/content/guides/developer/iota-chains/getting-started/tools.mdx index 633a16ee258..53566327fd4 100644 --- a/docs/content/guides/developer/iota-chains/getting-started/tools.mdx +++ b/docs/content/guides/developer/iota-chains/getting-started/tools.mdx @@ -19,12 +19,12 @@ tags: import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import {AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; -import HardhatConfig from '../_partials/_hardhat_config.mdx'; +import HardhatConfig from '../../../../_snippets/iota-chains/hardhat_config.mdx'; import { Networks } from '@theme/constant'; -import DeployAdmonition from '../_admonitions/_deploy_a_smart_contract.md'; +import DeployAdmonition from '../../../../_snippets/iota-chains/deploy_a_smart_contract.md'; import { ChainId } from '@theme/ChainId'; import NetworkInfo from '@theme/NetworkInfo'; -import OraclesContractData from '../_partials/_oracles_contract_data.mdx'; +import OraclesContractData from '../../../../_snippets/iota-chains/oracles_contract_data.mdx'; # Compatible Tools diff --git a/docs/content/guides/developer/iota-chains/how-tos/ERC20.mdx b/docs/content/guides/developer/iota-chains/how-tos/ERC20.mdx index 7afe3f22c44..99cfc64b3d7 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/ERC20.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/ERC20.mdx @@ -12,9 +12,9 @@ tags: - how to --- -import DeployAdmonition from '../_admonitions/_deploy_a_smart_contract.md'; -import PriorKnowledge from '../_admonitions/_EVM-required-prior-knowledge.md'; -import RemixIDE from '../_admonitions/_remix-IDE.md'; +import DeployAdmonition from '../../../../_snippets/iota-chains/deploy_a_smart_contract.md'; +import PriorKnowledge from '../../../../_snippets/iota-chains/EVM-required-prior-knowledge.md'; +import RemixIDE from '../../../../_snippets/iota-chains/remix-IDE.md'; # Create ERC20 Custom Tokens diff --git a/docs/content/guides/developer/iota-chains/how-tos/ERC721.mdx b/docs/content/guides/developer/iota-chains/how-tos/ERC721.mdx index 432b2e07b75..b81b02efdf5 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/ERC721.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/ERC721.mdx @@ -11,9 +11,9 @@ tags: - mint tokens - how to --- -import DeployAdmonition from '../_admonitions/_deploy_a_smart_contract.md'; -import PriorKnowledge from '../_admonitions/_EVM-required-prior-knowledge.md'; -import RemixIDE from '../_admonitions/_remix-IDE.md'; +import DeployAdmonition from '../../../../_snippets/iota-chains/deploy_a_smart_contract.md'; +import PriorKnowledge from '../../../../_snippets/iota-chains/EVM-required-prior-knowledge.md'; +import RemixIDE from '../../../../_snippets/iota-chains/remix-IDE.md'; # Create ERC721 NFTs diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/send-assets-to-l1.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/send-assets-to-l1.mdx index a479d9bb2c1..7c9278d3647 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/send-assets-to-l1.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/send-assets-to-l1.mdx @@ -10,7 +10,7 @@ tags: - Solidity --- -import AboutAccounts from '../../../_admonitions/_about-accounts.md'; +import AboutAccounts from '../../../../../../_snippets/iota-chains/about-accounts.md'; # Send Assets and Tokens to L1 diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx index f0fae55b102..ee36830fb40 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx @@ -6,7 +6,7 @@ tags: - EVM - how-to --- -import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.mdx'; +import ExampleCodeIntro from '../../../../../../_snippets/iota-chains/how-tos/token/example_code_intro.mdx'; # Mint an NFT ## About NFTs diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.mdx index 82e3f770c26..4c490a2ddb4 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.mdx @@ -6,8 +6,8 @@ tags: - EVM - how-to --- -import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.mdx'; -import ObsoleteTokenCreation from '../../../_partials/how-tos/token/_obsolete_token_creation.md'; +import ExampleCodeIntro from '../../../../../../_snippets/iota-chains/how-tos/token/example_code_intro.mdx'; +import ObsoleteTokenCreation from '../../../../../../_snippets/iota-chains/how-tos/token/obsolete_token_creation.md'; # Create a Foundry diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx index 84ed2433e4c..ec2f7e3f881 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx @@ -10,7 +10,7 @@ tags: - register --- -import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.mdx'; +import ExampleCodeIntro from '../../../../../../_snippets/iota-chains/how-tos/token/example_code_intro.mdx'; # Create a Native Token diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.mdx index 56918a7e83f..c6671c2682c 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.mdx @@ -8,7 +8,7 @@ tags: - native tokens - mint --- -import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.mdx'; +import ExampleCodeIntro from '../../../../../../_snippets/iota-chains/how-tos/token/example_code_intro.mdx'; # Mint Native Tokens diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/register-token.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/register-token.mdx index a97a64b88c7..9b004ab9290 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/register-token.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/register-token.mdx @@ -6,8 +6,8 @@ tags: - EVM - how-to --- -import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.mdx'; -import ObsoleteTokenCreation from '../../../_partials/how-tos/token/_obsolete_token_creation.md'; +import ExampleCodeIntro from '../../../../../../_snippets/iota-chains/how-tos/token/example_code_intro.mdx'; +import ObsoleteTokenCreation from '../../../../../../_snippets/iota-chains/how-tos/token/obsolete_token_creation.md'; # Register Tokens diff --git a/docs/content/guides/developer/iota-chains/how-tos/create-a-basic-contract.mdx b/docs/content/guides/developer/iota-chains/how-tos/create-a-basic-contract.mdx index d060b3732ff..5ec87ab79f2 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/create-a-basic-contract.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/create-a-basic-contract.mdx @@ -6,7 +6,7 @@ tags: - how to - basic contract --- -import DeployAdmonition from '../_admonitions/_deploy_a_smart_contract.md'; +import DeployAdmonition from '../../../../_snippets/iota-chains/deploy_a_smart_contract.md'; # Basic Smart Contract Example diff --git a/docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx b/docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx index efb531f634d..2c58738d73d 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx @@ -10,8 +10,8 @@ image: /img/logo/WASP_logo_dark.png description: 'Learn how to deploy smart contracts to IOTA EVM, Shimmer EVM and EVM Testnet using popular tools like Remix and Hardhat.' --- import {AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; -import HardhatConfig from '../_partials/_hardhat_config.mdx'; -import MetamaskButtons from '../_partials/_metamask_buttons.mdx'; +import HardhatConfig from '../../../../_snippets/iota-chains/hardhat_config.mdx'; +import MetamaskButtons from '../../../../_snippets/iota-chains/metamask_buttons.mdx'; import { Networks } from '@theme/constant'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; diff --git a/docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx b/docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx index 79fbec5304d..eb461e2cbc5 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx @@ -17,7 +17,7 @@ tags: import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import {AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; -import MetamaskButtons from '../_partials/_metamask_buttons.mdx'; +import MetamaskButtons from '../../../../_snippets/iota-chains/metamask_buttons.mdx'; import { Networks } from '@theme/constant'; # Send Funds From L1 to L2 diff --git a/docs/content/guides/developer/iota-chains/introduction.mdx b/docs/content/guides/developer/iota-chains/introduction.mdx index a82632b7e1c..06435430638 100644 --- a/docs/content/guides/developer/iota-chains/introduction.mdx +++ b/docs/content/guides/developer/iota-chains/introduction.mdx @@ -11,7 +11,7 @@ tags: - explanation --- -import OnOffLedgerRequest from './_partials/_on_off_ledger_request.md'; +import OnOffLedgerRequest from '../../../_snippets/iota-chains/on_off_ledger_request.md'; # Introduction From ffd2f90d81ad4a41738a9b02a642f1b8b1f07309 Mon Sep 17 00:00:00 2001 From: Jeroen van den Hout Date: Mon, 10 Jun 2024 23:35:33 +0200 Subject: [PATCH 17/37] fix(docs): apply correct paths to references --- .../iota-chains/explanations/core-contracts.md | 14 +++++++------- .../iota-chains/explanations/how-accounts-work.md | 2 +- .../iota-chains/explanations/invocation.mdx | 2 +- .../explanations/smart-contract-anatomy.md | 4 ++-- .../iota-chains/explanations/validators.md | 2 +- .../iota-chains/getting-started/compatibility.md | 2 +- .../getting-started/languages-and-vms.mdx | 2 +- .../getting-started/networks-and-chains.mdx | 4 ++-- .../how-tos/core-contracts/call-view.md | 6 +++--- .../how-tos/core-contracts/introduction.md | 8 ++++---- .../how-tos/core-contracts/nft/mint-nft.mdx | 6 +++--- .../core-contracts/token/create-native-token.mdx | 6 +++--- .../developer/iota-chains/schema/how-tos/state.mdx | 2 +- .../iota-chains/schema/how-tos/typedefs.mdx | 2 +- .../iota-chains/solo/how-tos/error-handling.md | 2 +- .../iota-chains/solo/how-tos/first-example.md | 6 +++--- .../developer/iota-chains/solo/how-tos/test.mdx | 2 +- .../iota-chains/solo/how-tos/the-l2-ledger.md | 6 +++--- .../developer/iota-chains/solo/how-tos/view-sc.md | 2 +- .../iota-chains-node/how-tos/chain-management.md | 2 +- .../iota-chains-node/how-tos/setting-up-a-chain.md | 4 ++-- 21 files changed, 43 insertions(+), 43 deletions(-) diff --git a/docs/content/guides/developer/iota-chains/explanations/core-contracts.md b/docs/content/guides/developer/iota-chains/explanations/core-contracts.md index acfdbf5e22c..bdade2dfdd7 100644 --- a/docs/content/guides/developer/iota-chains/explanations/core-contracts.md +++ b/docs/content/guides/developer/iota-chains/explanations/core-contracts.md @@ -21,17 +21,17 @@ There are currently 7 core smart contracts that are always deployed on each chain. These are responsible for the vital functions of the chain and provide infrastructure for all other smart contracts: -- [`root`](../reference/core-contracts/root.md): Responsible for the initialization of the chain, maintains registry of deployed contracts. +- [`root`](../../../../references/iota-chains/core-contracts/root.md): Responsible for the initialization of the chain, maintains registry of deployed contracts. -- [`accounts`](../reference/core-contracts/accounts.md): Manages the on-chain ledger of accounts. +- [`accounts`](../../../../references/iota-chains/core-contracts/accounts.md): Manages the on-chain ledger of accounts. -- [`blob`](../reference/core-contracts/blob.md): Responsible for the registry of binary objects of arbitrary size. +- [`blob`](../../../../references/iota-chains/core-contracts/blob.md): Responsible for the registry of binary objects of arbitrary size. -- [`blocklog`](../reference/core-contracts/blocklog.md): Keeps track of the blocks and receipts of requests that were processed by the chain. +- [`blocklog`](../../../../references/iota-chains/core-contracts/blocklog.md): Keeps track of the blocks and receipts of requests that were processed by the chain. -- [`governance`](../reference/core-contracts/governance.md): Handles the administrative functions of the chain. For example: rotation of the committee of validators of the chain, fees and other chain-specific configurations. +- [`governance`](../../../../references/iota-chains/core-contracts/governance.md): Handles the administrative functions of the chain. For example: rotation of the committee of validators of the chain, fees and other chain-specific configurations. -- [`errors`](../reference/core-contracts/errors.md): Keeps a map of error codes to error messages templates. These error codes are used in request receipts. +- [`errors`](../../../../references/iota-chains/core-contracts/errors.md): Keeps a map of error codes to error messages templates. These error codes are used in request receipts. -- [`evm`](../reference/core-contracts/evm.md): Provides the necessary infrastructure to accept Ethereum +- [`evm`](../../../../references/iota-chains/core-contracts/evm.md): Provides the necessary infrastructure to accept Ethereum transactions and execute EVM code. diff --git a/docs/content/guides/developer/iota-chains/explanations/how-accounts-work.md b/docs/content/guides/developer/iota-chains/explanations/how-accounts-work.md index 348455d1cf7..1f2398d2ded 100644 --- a/docs/content/guides/developer/iota-chains/explanations/how-accounts-work.md +++ b/docs/content/guides/developer/iota-chains/explanations/how-accounts-work.md @@ -74,7 +74,7 @@ Tokens in an Ethereum account can only be moved by sending an Ethereum transacti ## The Accounts Contract -The [`accounts` core contract](../reference/core-contracts/accounts.md) is responsible for managing the L2 ledger. +The [`accounts` core contract](../../../../references/iota-chains/core-contracts/accounts.md) is responsible for managing the L2 ledger. By calling this contract, it is possible to: - [View current account balances](../how-tos/core-contracts/basics/get-balance.md) diff --git a/docs/content/guides/developer/iota-chains/explanations/invocation.mdx b/docs/content/guides/developer/iota-chains/explanations/invocation.mdx index 20f7c54c9d3..9d40696a8bc 100644 --- a/docs/content/guides/developer/iota-chains/explanations/invocation.mdx +++ b/docs/content/guides/developer/iota-chains/explanations/invocation.mdx @@ -78,7 +78,7 @@ as token swaps can require more due to the higher computational work involved. For users to specify how much they're willing to pay for a request, they need to specify a `GasBudget` in the request. This gas budget is the "maximum operations that this request can execute" and will be charged as a fee based on the -chain's current [fee policy](../reference/core-contracts/governance.md#fee-policy). +chain's current [fee policy](../../../../references/iota-chains/core-contracts/governance.md#fee-policy). The funds to cover the gas used will be charged directly from the user's on-chain account. diff --git a/docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md b/docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md index 76a3c1b96ec..449263fdc28 100644 --- a/docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md +++ b/docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md @@ -25,7 +25,7 @@ contracts coexisting on the same chain. The ISC [core contracts](core-contracts.md) and WASM contracts on the chain are identified by a _hname_ (pronounced "aitch-name"), which is a `uint32` value calculated as a hash of the smart contract's instance name (a string). -For example, the hname of the [`root`](../reference/core-contracts/root.md) core contract +For example, the hname of the [`root`](../../../../references/iota-chains/core-contracts/root.md) core contract is `0xcebf5908`. This value uniquely identifies this contract in every chain. This does not apply to EVM contracts. ## State @@ -65,7 +65,7 @@ There are two types of entry points: ## Execution Results After a request to a Smart Contract is executed (a call to a full entry point), a _receipt_ will be added to -the [`blocklog`](../reference/core-contracts/blocklog.md) core contract. The receipt details the +the [`blocklog`](../../../../references/iota-chains/core-contracts/blocklog.md) core contract. The receipt details the execution results of said request: whether it was successful, the block it was included in, and other information. Any events dispatched by the smart contract in context of this execution will also be added to the receipt. diff --git a/docs/content/guides/developer/iota-chains/explanations/validators.md b/docs/content/guides/developer/iota-chains/explanations/validators.md index 97ed59a19c0..31a3db68939 100644 --- a/docs/content/guides/developer/iota-chains/explanations/validators.md +++ b/docs/content/guides/developer/iota-chains/explanations/validators.md @@ -46,4 +46,4 @@ It is common for validator nodes to be part of a private subnet and have only a outside world, protecting the committee from external attacks. The management of validator and access nodes is done through -the [`governance` core contract](../reference/core-contracts/governance.md). +the [`governance` core contract](../../../../references/iota-chains/core-contracts/governance.md). diff --git a/docs/content/guides/developer/iota-chains/getting-started/compatibility.md b/docs/content/guides/developer/iota-chains/getting-started/compatibility.md index 94cd946d381..3103f0273fc 100644 --- a/docs/content/guides/developer/iota-chains/getting-started/compatibility.md +++ b/docs/content/guides/developer/iota-chains/getting-started/compatibility.md @@ -14,7 +14,7 @@ tags: # EVM Compatibility in IOTA Smart Contracts -The [`evm`](../reference/core-contracts/evm.md) [core contract](../reference/core-contracts/overview.md) +The [`evm`](../../../../references/iota-chains/core-contracts/evm.md) [core contract](../../../../references/iota-chains/core-contracts/overview.md) provides EVM support in IOTA Smart Contracts. It stores the EVM state (account balances, state, code, etc.) and provides a way to execute EVM code to manipulate the state. diff --git a/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.mdx b/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.mdx index e5f2f7a5303..b316deb450c 100644 --- a/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.mdx +++ b/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.mdx @@ -37,7 +37,7 @@ changes to function on IOTA Smart Contracts. ### How IOTA Smart Contracts Work With EVM Every deployed ISC chain automatically includes a core contract -called [`evm`](../reference/core-contracts/evm.md). This core contract is responsible for running EVM code and +called [`evm`](../../../../references/iota-chains/core-contracts/evm.md). This core contract is responsible for running EVM code and storing the EVM state. The Wasp node also provides a standard JSON-RPC service, which allows you to interact with the EVM layer using existing diff --git a/docs/content/guides/developer/iota-chains/getting-started/networks-and-chains.mdx b/docs/content/guides/developer/iota-chains/getting-started/networks-and-chains.mdx index cc3796b00ed..1e26373a132 100644 --- a/docs/content/guides/developer/iota-chains/getting-started/networks-and-chains.mdx +++ b/docs/content/guides/developer/iota-chains/getting-started/networks-and-chains.mdx @@ -139,5 +139,5 @@ The other values (network name and currency symbol) can be whatever value you li ## Core Contracts [IOTA EVM](#IOTAEVM), [ShimmerEVM](#shimmerEVM) and the testnet networks have 7 -[core contracts](../reference/core-contracts/overview.md) deployed, as well as the -[Magic Contract](../reference/magic-contract/introduction.md). +[core contracts](../../../../references/iota-chains/core-contracts/overview.md) deployed, as well as the +[Magic Contract](../../../../references/iota-chains/magic-contract/introduction.md). diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/call-view.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/call-view.md index d66fe7c9726..dbccbb974e4 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/call-view.md +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/call-view.md @@ -14,7 +14,7 @@ tags: ## About `call` and `callView` -The magic contract provides you with a solidity interface to the core contracts. Some functions like [`getL2BalanceBaseTokens`](../../reference/magic-contract/ISCAccounts.md#getl2balancebasetokens) are wrapped in the magic contract directly, others you need to call yourself. You can do that with the [`call`](../../reference/magic-contract/ISCSandbox.md#call) and [`callView`](../../reference/magic-contract/ISCSandbox.md#callview) functions. +The magic contract provides you with a solidity interface to the core contracts. Some functions like [`getL2BalanceBaseTokens`](../../../../../references/iota-chains/magic-contract/ISCAccounts.md#getl2balancebasetokens) are wrapped in the magic contract directly, others you need to call yourself. You can do that with the [`call`](../../../../../references/iota-chains/magic-contract/ISCSandbox.md#call) and [`callView`](../../../../../references/iota-chains/magic-contract/ISCSandbox.md#callview) functions. :::info WASM @@ -30,7 +30,7 @@ You can also use `call` and `callView` to interact with WASM contracts. ISCAgentID memory agentID = ISC.sandbox.getSenderAccount(); ``` -2. Initialize the parameters for the call by creating a new [`ISCDict`](../../reference/magic-contract/ISCTypes.md#iscdict). As you can see in the docs, [`getl2balancenativetokens`](../../reference/magic-contract/ISCAccounts.md#getl2balancenativetokens) takes two parameters.: the Agent ID and the native token ID. So, you have to create a dictionary with two key-value pairs. The key of the first pair (Agent ID) has to be `a` and the key for the second pair (native token ID) `N`. +2. Initialize the parameters for the call by creating a new [`ISCDict`](../../../../../references/iota-chains/magic-contract/ISCTypes.md#iscdict). As you can see in the docs, [`getl2balancenativetokens`](../../../../../references/iota-chains/magic-contract/ISCAccounts.md#getl2balancenativetokens) takes two parameters.: the Agent ID and the native token ID. So, you have to create a dictionary with two key-value pairs. The key of the first pair (Agent ID) has to be `a` and the key for the second pair (native token ID) `N`. ```solidity ISCDict memory params = ISCDict(new ISCDictItem[](2)); @@ -38,7 +38,7 @@ params.items[0] = ISCDictItem("a", agentID.data); params.items[1] = ISCDictItem("N", nativeTokenID); ``` -3. Now, you can use [`callView`](../../reference/magic-contract/ISCSandbox.md#callview) to call our contract. The first parameter is the core contract `hname`, which we can get with the helper utility [`hn`](../../reference/magic-contract/ISCUtil.md#hn), and the second parameter is the function we want to call. The last parameter is the dictionary with all function parameters. +3. Now, you can use [`callView`](../../../../../references/iota-chains/magic-contract/ISCSandbox.md#callview) to call our contract. The first parameter is the core contract `hname`, which we can get with the helper utility [`hn`](../../../../../references/iota-chains/magic-contract/ISCUtil.md#hn), and the second parameter is the function we want to call. The last parameter is the dictionary with all function parameters. ```solidity ISCDict memory result = ISC.sandbox.callView( diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/introduction.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/introduction.md index d8983b4e246..9396e8d73ba 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/introduction.md +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/introduction.md @@ -15,14 +15,14 @@ tags: # The Core Contracts -The [core contracs](../../explanations/core-contracts.md) are contracts deployed on every chain and are vital to interact with L1 and the chain itself. They can be called in Solidity through the [ISC Magic Contract](../../reference/magic-contract/introduction.md). +The [core contracs](../../explanations/core-contracts.md) are contracts deployed on every chain and are vital to interact with L1 and the chain itself. They can be called in Solidity through the [ISC Magic Contract](../../../../../references/iota-chains/magic-contract/introduction.md). ## The ISC Magic Contract The Magic contract is an EVM contract deployed by default on every ISC chain, in the EVM genesis block, at address `0x1074000000000000000000000000000000000000`. The implementation of the Magic contract is baked-in in -the [`evm`](../../reference/core-contracts/evm.md) [core contract](../../reference/core-contracts/overview.md); +the [`evm`](../../../../../references/iota-chains/core-contracts/evm.md) [core contract](../../../../../references/iota-chains/core-contracts/overview.md); i.e. it is not a pure-Solidity contract. The Magic contract has several methods, which are categorized into specialized @@ -45,7 +45,7 @@ tokens and native tokens on L2. :::info Reference Docs -If you need further info about magic contracts interfaces you can check out the [magic contract docs](../../reference/magic-contract/introduction.md). +If you need further info about magic contracts interfaces you can check out the [magic contract docs](../../../../../references/iota-chains/magic-contract/introduction.md). ::: @@ -53,7 +53,7 @@ If you need further info about magic contracts interfaces you can check out the :::info Ease of use -To make it easier for developers to use the core contracts, you should, in most cases, run the functions from the magic contract directly. For example, to get the native token balance, you could [call the `balanceNativeToken()`](./call-view.md) directly with `callView`, or use [`getl2balancenativetokens`](./basics/get-balance.md) of the magic contract, or (the suggested way) register your native token as [`ERC20`](../../reference/magic-contract/ERC20NativeTokens.md) and call the standard [`balanceof`](../../reference/magic-contract/ERC20NativeTokens.md#balanceof) function. What you use also depends on what you optimize for. For example, to save gas, it could be interesting for you to call core contracts from your favorite web3 library directly and compute other things off-chain. +To make it easier for developers to use the core contracts, you should, in most cases, run the functions from the magic contract directly. For example, to get the native token balance, you could [call the `balanceNativeToken()`](./call-view.md) directly with `callView`, or use [`getl2balancenativetokens`](./basics/get-balance.md) of the magic contract, or (the suggested way) register your native token as [`ERC20`](../../../../../references/iota-chains/magic-contract/ERC20NativeTokens.md) and call the standard [`balanceof`](../../../../../references/iota-chains/magic-contract/ERC20NativeTokens.md#balanceof) function. What you use also depends on what you optimize for. For example, to save gas, it could be interesting for you to call core contracts from your favorite web3 library directly and compute other things off-chain. ::: diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx index ee36830fb40..b66bd8f15eb 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx @@ -35,7 +35,7 @@ IRC27NFTMetadata memory metadata = IRC27NFTMetadata({ }); ``` -4. Create all the data for the core contract call. To do so, you should create a new `ISCDict` with 2 parameters like specified in the reference docs for [`mintNFT`](../../../reference/core-contracts/accounts.md#mintnfti-immutabledata-a-agentid-c-collectionid-w-withdrawonmint) +4. Create all the data for the core contract call. To do so, you should create a new `ISCDict` with 2 parameters like specified in the reference docs for [`mintNFT`](../../../../../../references/iota-chains/core-contracts/accounts.md#mintnfti-immutabledata-a-agentid-c-collectionid-w-withdrawonmint) * `I` is the immutable metadata we fill with the IRC27 metadata and * `a` is the AgendID of the owner of the NFT @@ -51,7 +51,7 @@ The full example below calls the `IRC27NFTMetadataToString` function, which simp ::: -5. Call the magic contract `call` function with all the parameters. You should specify the core contract you want to call, which in this case is the [`account`](../../../reference/core-contracts/accounts.md) contract, and the function for [minting an NFT](../../../reference/core-contracts/accounts.md#mintnfti-immutabledata-a-agentid-c-collectionid-w-withdrawonmint) +5. Call the magic contract `call` function with all the parameters. You should specify the core contract you want to call, which in this case is the [`account`](../../../../../../references/iota-chains/core-contracts/accounts.md) contract, and the function for [minting an NFT](../../../../../../references/iota-chains/core-contracts/accounts.md#mintnfti-immutabledata-a-agentid-c-collectionid-w-withdrawonmint) ```solidity ISCDict memory ret = ISC.sandbox.call( @@ -62,7 +62,7 @@ ISCDict memory ret = ISC.sandbox.call( ); ``` -6. The call return value will contain a `mintID` which we can use in, for example, another contract function to get the actual L1 NFT ID once it is created using the [`accounts.NFTIDbyMintID`](../../../reference/core-contracts/accounts.md#nftidbymintidd-mintid) function +6. The call return value will contain a `mintID` which we can use in, for example, another contract function to get the actual L1 NFT ID once it is created using the [`accounts.NFTIDbyMintID`](../../../../../../references/iota-chains/core-contracts/accounts.md#nftidbymintidd-mintid) function ```solidity function getNFTIDFromMintID(bytes memory mintID) public view returns (bytes memory) { diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx index ec2f7e3f881..bd099e410b9 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx @@ -14,7 +14,7 @@ import ExampleCodeIntro from '../../../../../../_snippets/iota-chains/how-tos/to # Create a Native Token -This guide will show you how you can efficiently mint new tokens and register them for use as ERC20 tokens with the [`createNativeTokenFoundry`](../../../reference/magic-contract/ISCAccounts.md#createnativetokenfoundry) function in one seamless operation. It will create a foundry on L1 and register it as an ERC20 on L2. This method ensures that only the foundry owner can mint tokens, maintaining security and control over the token creation process. +This guide will show you how you can efficiently mint new tokens and register them for use as ERC20 tokens with the [`createNativeTokenFoundry`](../../../../../../references/iota-chains/magic-contract/ISCAccounts.md#createnativetokenfoundry) function in one seamless operation. It will create a foundry on L1 and register it as an ERC20 on L2. This method ensures that only the foundry owner can mint tokens, maintaining security and control over the token creation process. ## About Foundries @@ -27,7 +27,7 @@ The Foundry lets you specify your native token's maximum supply **once** and cha ### 2. Define the Token Scheme -Define the [`NativeTokenScheme`](../../../reference/magic-contract/ISCTypes.md#nativetokenscheme) by specifying the `maximumSupply`. +Define the [`NativeTokenScheme`](../../../../../../references/iota-chains/magic-contract/ISCTypes.md#nativetokenscheme) by specifying the `maximumSupply`. ```solidity NativeTokenScheme memory nativeTokenScheme = NativeTokenScheme({ @@ -39,7 +39,7 @@ NativeTokenScheme memory nativeTokenScheme = NativeTokenScheme({ ### 3. Mint and Register Native Token -Minting native tokens and registering them as ERC20 tokens using [`createNativeTokenFoundry`](../../../reference/magic-contract/ISCAccounts.md#createnativetokenfoundry) method +Minting native tokens and registering them as ERC20 tokens using [`createNativeTokenFoundry`](../../../../../../references/iota-chains/magic-contract/ISCAccounts.md#createnativetokenfoundry) method ```solidity uint32 foundrySN = ISC.accounts.createNativeTokenFoundry( diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/state.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/state.mdx index 70252bfb4a1..4a8d2e4d425 100644 --- a/docs/content/guides/developer/iota-chains/schema/how-tos/state.mdx +++ b/docs/content/guides/developer/iota-chains/schema/how-tos/state.mdx @@ -55,7 +55,7 @@ state: Starting with straightforward state variables, `totalFactor`, and `owner` are characterized as Uint64 and AgentID, respectively. -These represent predefined [WasmLib value types](../../reference/wasm-lib-data-types.mdx). +These represent predefined [WasmLib value types](../../../../../references/iota-chains/wasm-lib-data-types.mdx). ### Arrays and Maps diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/typedefs.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/typedefs.mdx index 2d55e859696..d56b98a2adb 100644 --- a/docs/content/guides/developer/iota-chains/schema/how-tos/typedefs.mdx +++ b/docs/content/guides/developer/iota-chains/schema/how-tos/typedefs.mdx @@ -19,7 +19,7 @@ import TabItem from '@theme/TabItem'; :::note WasmLib Types -You can find the complete list of [WasmLib Data Types](../../reference/wasm-lib-data-types.mdx) in the reference section. +You can find the complete list of [WasmLib Data Types](../../../../../references/iota-chains/wasm-lib-data-types.mdx) in the reference section. ::: diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/error-handling.md b/docs/content/guides/developer/iota-chains/solo/how-tos/error-handling.md index 40b414feedc..a22ac10f734 100644 --- a/docs/content/guides/developer/iota-chains/solo/how-tos/error-handling.md +++ b/docs/content/guides/developer/iota-chains/solo/how-tos/error-handling.md @@ -44,7 +44,7 @@ Note that this test still ends with the state `#4`, although the last request to ``` This shows that a chain block is always generated, regardless of whether the smart contract call succeeds or not. The -result of the request is stored in the chain's [`blocklog`](../../reference/core-contracts/blocklog.md) in the form of +result of the request is stored in the chain's [`blocklog`](../../../../../references/iota-chains/core-contracts/blocklog.md) in the form of a receipt. In fact, the received Go error `err` in the test above is just generated from the request receipt. If a panic occurs during a smart contract call, it is recovered by the VM context, and the request is marked as failed. diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/first-example.md b/docs/content/guides/developer/iota-chains/solo/how-tos/first-example.md index f4189cee840..c4ba435ebe9 100644 --- a/docs/content/guides/developer/iota-chains/solo/how-tos/first-example.md +++ b/docs/content/guides/developer/iota-chains/solo/how-tos/first-example.md @@ -13,8 +13,8 @@ tags: # First Example The following is an example of a _Solo_ test. It deploys a new chain and invokes some view calls in the -[`root`](../../reference/core-contracts/root.md) and [`governance`](../../reference/core-contracts/governance.md) -[core contracts](../../reference/core-contracts/overview.md). +[`root`](../../../../../references/iota-chains/core-contracts/root.md) and [`governance`](../../../../../references/iota-chains/core-contracts/governance.md) +[core contracts](../../../../../references/iota-chains/core-contracts/overview.md). ```go import ( @@ -81,7 +81,7 @@ The output of the test will be something like this: ::: -The [core contracts](../../reference/core-contracts/overview.md) listed in the log are automatically deployed on each +The [core contracts](../../../../../references/iota-chains/core-contracts/overview.md) listed in the log are automatically deployed on each new chain. The log also shows their _contract IDs_. The output fragment in the log `state transition --> #1` means that the state of the chain has changed from block index diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/test.mdx b/docs/content/guides/developer/iota-chains/solo/how-tos/test.mdx index aedbaab2e19..d3ea808bd32 100644 --- a/docs/content/guides/developer/iota-chains/solo/how-tos/test.mdx +++ b/docs/content/guides/developer/iota-chains/solo/how-tos/test.mdx @@ -26,7 +26,7 @@ combination with Solo to deploy chains and smart contracts and simulate transact Solo directly interacts with the ISC code, and therfore uses all the ISC-specific data types directly. Our Wasm smart contracts cannot access these types directly, because they run in a separate, sandboxed environment. Therefore, WasmLib implements its -[own versions](../../reference/wasm-lib-data-types.mdx) of these data types, and the _VM_ layer acts as a data type +[own versions](../../../../../references/iota-chains/wasm-lib-data-types.mdx) of these data types, and the _VM_ layer acts as a data type translator between both systems. The impact of this type transformation used to be that to be able to write tests in the diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/the-l2-ledger.md b/docs/content/guides/developer/iota-chains/solo/how-tos/the-l2-ledger.md index ed737dbeaed..58dd8b2c0b4 100644 --- a/docs/content/guides/developer/iota-chains/solo/how-tos/the-l2-ledger.md +++ b/docs/content/guides/developer/iota-chains/solo/how-tos/the-l2-ledger.md @@ -100,10 +100,10 @@ func TestTutorialAccounts(t *testing.T) { The example above creates a chain and a wallet with `utxodb.FundsFromFaucetAmount` base tokens on L1. Then, it sends 1 million tokens to the corresponding on-chain account by posting a -[`deposit`](../../reference/core-contracts/accounts.md#deposit) request to the -[`accounts` core contract](../../reference/core-contracts/accounts.md) on the chain. +[`deposit`](../../../../../references/iota-chains/core-contracts/accounts.md#deposit) request to the +[`accounts` core contract](../../../../../references/iota-chains/core-contracts/accounts.md) on the chain. -Finally, it sends a [`withdraw`](../../reference/core-contracts/accounts.md#withdraw) request to the `accounts` core +Finally, it sends a [`withdraw`](../../../../../references/iota-chains/core-contracts/accounts.md#withdraw) request to the `accounts` core contract to get the tokens back to L1. Both requests are affected by the gas fees and the storage deposit. diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/view-sc.md b/docs/content/guides/developer/iota-chains/solo/how-tos/view-sc.md index df59550462a..7b61257759b 100644 --- a/docs/content/guides/developer/iota-chains/solo/how-tos/view-sc.md +++ b/docs/content/guides/developer/iota-chains/solo/how-tos/view-sc.md @@ -33,7 +33,7 @@ view entry point will result in an exception, returning all attached tokens to t Views are used to retrieve information about the smart contract's state, for example, to display on a website. Certain Solo methods such as `chain.GetInfo`, `chain.GetGasFeePolicy`, and `chain.L2Assets` call views of -the [core smart contracts](../../reference/core-contracts/overview.md) behind the scenes to retrieve the information +the [core smart contracts](../../../../../references/iota-chains/core-contracts/overview.md) behind the scenes to retrieve the information about the chain or a specific smart contract. ## Decoding Results Returned by _PostRequestSync_ and _CallView_ diff --git a/docs/content/guides/operator/iota-chains-node/how-tos/chain-management.md b/docs/content/guides/operator/iota-chains-node/how-tos/chain-management.md index b6273d1dd93..e59df73e16c 100644 --- a/docs/content/guides/operator/iota-chains-node/how-tos/chain-management.md +++ b/docs/content/guides/operator/iota-chains-node/how-tos/chain-management.md @@ -20,7 +20,7 @@ You can view the chain state using the dashboard (`/wasp/dashboard` when us ## Manage Chain Configuration and Validators You can manage the chain configuration and committee of validators by interacting with -the [Governance contract](/isc/reference/core-contracts/governance). +the [Governance contract](/isc/../../../references/iota-chains/core-contracts/governance). The “Chain Owner” is the only one who can perform administrative tasks. diff --git a/docs/content/guides/operator/iota-chains-node/how-tos/setting-up-a-chain.md b/docs/content/guides/operator/iota-chains-node/how-tos/setting-up-a-chain.md index d71c78d5372..ab8a5f90337 100644 --- a/docs/content/guides/operator/iota-chains-node/how-tos/setting-up-a-chain.md +++ b/docs/content/guides/operator/iota-chains-node/how-tos/setting-up-a-chain.md @@ -84,7 +84,7 @@ From now on, all chain commands will target this chain. The `--quorum` flag indicates the minimum number of nodes required to form a _consensus_. The recommended formula to obtain this number is `floor(N*2/3)+1` where `N` is the number of nodes in your committee. -The `--block-keep-amount` parameter determines how many blocks are stored in the [`blocklog`](/isc/reference/core-contracts/blocklog) core contract. +The `--block-keep-amount` parameter determines how many blocks are stored in the [`blocklog`](/isc/../../../references/iota-chains/core-contracts/blocklog) core contract. After deployment, the chain must be activated by the node operators of all peers. @@ -96,7 +96,7 @@ wasp-cli chain activate --chain= ## Test If It Works You can check that the chain was deployed correctly in the Wasp node dashboard (`/wasp/dashboard` when using `node-docker-setup`). -Note that the chain was deployed with some [core contracts](/isc/reference/core-contracts/overview). +Note that the chain was deployed with some [core contracts](/isc/../../../references/iota-chains/core-contracts/overview). You should also have an EVM-JSONRPC server opened on: From 86ef184692aaeff7d0f70631010936da818e4bf3 Mon Sep 17 00:00:00 2001 From: Jeroen van den Hout Date: Tue, 11 Jun 2024 00:22:50 +0200 Subject: [PATCH 18/37] fix(docs): fix paths --- .../iota-chains/EVM-required-prior-knowledge.md | 2 +- .../_snippets/iota-chains/EVM_compatibility.md | 4 ++-- docs/content/_snippets/iota-chains/about-accounts.md | 2 +- .../how-tos/token/obsolete_token_creation.md | 2 +- .../iota-chains/core-contracts/accounts.md | 2 +- .../references/iota-chains/core-contracts/evm.md | 4 ++-- .../references/iota-chains/wasm-lib-data-types.mdx | 12 ++++++------ 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/content/_snippets/iota-chains/EVM-required-prior-knowledge.md b/docs/content/_snippets/iota-chains/EVM-required-prior-knowledge.md index c1e17089a98..18f71c69ee4 100644 --- a/docs/content/_snippets/iota-chains/EVM-required-prior-knowledge.md +++ b/docs/content/_snippets/iota-chains/EVM-required-prior-knowledge.md @@ -8,7 +8,7 @@ EIP)) , [NFTs](/learn/protocols/stardust/core-concepts/multi-asset-ledger#non-fungible-tokens-nfts), [Smart Contracts](/learn/smart-contracts/introduction) and have already tinkered with [Solidity](https://docs.soliditylang.org/en/v0.8.16/). -You should also have basic knowledge on how to [create](../how-tos/create-a-basic-contract.md) and [deploy](../how-tos/deploy-a-smart-contract.mdx) +You should also have basic knowledge on how to [create](../../guides/developer/iota-chains/how-tos/create-a-basic-contract.mdx) and [deploy](../../guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx) a smart contract. ::: \ No newline at end of file diff --git a/docs/content/_snippets/iota-chains/EVM_compatibility.md b/docs/content/_snippets/iota-chains/EVM_compatibility.md index 1f20154e1ea..cc795c81634 100644 --- a/docs/content/_snippets/iota-chains/EVM_compatibility.md +++ b/docs/content/_snippets/iota-chains/EVM_compatibility.md @@ -1,7 +1,7 @@ :::info EVM Compatibility The ISC EVM layer is also designed to be as compatible as possible with existing Ethereum -[tools](../getting-started/tools.mdx) and functionalities. However, please make sure you have checked out the current -[properties and limitations](../getting-started/compatibility.md). +[tools](../../guides/developer/iota-chains/getting-started/tools.mdx) and functionalities. However, please make sure you have checked out the current +[properties and limitations](../../guides/developer/iota-chains/getting-started/compatibility.md). ::: \ No newline at end of file diff --git a/docs/content/_snippets/iota-chains/about-accounts.md b/docs/content/_snippets/iota-chains/about-accounts.md index 4095981384d..aa3b44942eb 100644 --- a/docs/content/_snippets/iota-chains/about-accounts.md +++ b/docs/content/_snippets/iota-chains/about-accounts.md @@ -1,5 +1,5 @@ :::info Accounts in ISC -Learn more about the [different types of accounts](../explanations/how-accounts-work.md). +Learn more about the [different types of accounts](../../guides/developer/iota-chains/explanations/how-accounts-work.md). ::: \ No newline at end of file diff --git a/docs/content/_snippets/iota-chains/how-tos/token/obsolete_token_creation.md b/docs/content/_snippets/iota-chains/how-tos/token/obsolete_token_creation.md index 1a70e93ffaa..ae8b77287db 100644 --- a/docs/content/_snippets/iota-chains/how-tos/token/obsolete_token_creation.md +++ b/docs/content/_snippets/iota-chains/how-tos/token/obsolete_token_creation.md @@ -1,5 +1,5 @@ :::caution -This method is now obsolete, use the new [`createNativeTokenFoundry`](../../../how-tos/core-contracts/token/create-native-token.md) method instead. +This method is now obsolete, use the new [`createNativeTokenFoundry`](../../../../guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx) method instead. ::: \ No newline at end of file diff --git a/docs/content/references/iota-chains/core-contracts/accounts.md b/docs/content/references/iota-chains/core-contracts/accounts.md index 18a3f77e787..db984f9d793 100644 --- a/docs/content/references/iota-chains/core-contracts/accounts.md +++ b/docs/content/references/iota-chains/core-contracts/accounts.md @@ -17,7 +17,7 @@ The `accounts` contract is one of the [core contracts](overview.md) on each IOTA chain. This contract keeps a consistent ledger of on-chain accounts in its state, -i.e. [the L2 ledger](../../explanations/how-accounts-work.md). +i.e. [the L2 ledger](../../../guides/developer/iota-chains/explanations/how-accounts-work.md). --- diff --git a/docs/content/references/iota-chains/core-contracts/evm.md b/docs/content/references/iota-chains/core-contracts/evm.md index 99be19b75bc..19257df3c7b 100644 --- a/docs/content/references/iota-chains/core-contracts/evm.md +++ b/docs/content/references/iota-chains/core-contracts/evm.md @@ -20,11 +20,11 @@ tags: The `evm` contract is one of the [core contracts](overview.md) on each IOTA Smart Contracts chain. The `evm` core contract provides the necessary infrastructure to accept Ethereum transactions and execute EVM code. -It also includes the implementation of the [ISC Magic contract](../../how-tos/core-contracts/introduction.md). +It also includes the implementation of the [ISC Magic contract](../../../guides/developer/iota-chains/how-tos/core-contracts/introduction.md). :::note -For more information about how ISC supports EVM contracts, refer to the [EVM](../../getting-started/languages-and-vms.md#evmsolidity-based-smart-contracts) section. +For more information about how ISC supports EVM contracts, refer to the [EVM](../../../guides/developer/iota-chains/getting-started/languages-and-vms.mdx#evmsolidity-based-smart-contracts) section. ::: diff --git a/docs/content/references/iota-chains/wasm-lib-data-types.mdx b/docs/content/references/iota-chains/wasm-lib-data-types.mdx index 28789a1772d..a0efcc72df5 100644 --- a/docs/content/references/iota-chains/wasm-lib-data-types.mdx +++ b/docs/content/references/iota-chains/wasm-lib-data-types.mdx @@ -23,7 +23,7 @@ as human-readable text string. These are mostly simple built-in scalar data types as provided by most programming languages. Each integer data type has a clearly defined storage size. The -[Schema Tool](../schema/how-tos/usage.mdx) will attempt to use the closest matching built-in data type when +[Schema Tool](../../guides/developer/iota-chains/schema/how-tos/usage.mdx) will attempt to use the closest matching built-in data type when generating code for a specific language. - `BigInt` - An arbitrary-length unsigned integer. @@ -55,7 +55,7 @@ WasmLib provides its own implementations for each of the ISC value data types. ## Full Matrix of WasmLib Types -WasmLib implements a full set of [value proxies](../schema/proxies.mdx#value-proxies) for each +WasmLib implements a full set of [value proxies](../../guides/developer/iota-chains/schema/proxies.mdx#value-proxies) for each predefined value type that provide access to data on the ISC host. But there is one aspect of this data that we have not considered yet. Some data provided by the host is mutable, whereas other data may be immutable. To facilitate this distinction, each value proxy type @@ -97,8 +97,8 @@ The consistent naming makes it easy to remember the type names. Bool, Bytes, Str the integer types are the odd ones out. They are implemented in WasmLib by the closest equivalents in the chosen WasmLib implementation programming language. -The [Schema Tool](../schema/how-tos/usage.mdx) will automatically generate the proper immutable proxies +The [Schema Tool](../../guides/developer/iota-chains/schema/how-tos/usage.mdx) will automatically generate the proper immutable proxies from the schema definition. For example, View functions will only be able to access the -[State](../schema/how-tos/state.mdx) map through immutable proxies. The same goes for the -[Params](../schema/how-tos/params.mdx) map that was passed into a Func or View, and for the -[Results](../schema/how-tos/results.mdx) map that was returned from a call to a Func or View. +[State](../../guides/developer/iota-chains/schema/how-tos/state.mdx) map through immutable proxies. The same goes for the +[Params](../../guides/developer/iota-chains/schema/how-tos/params.mdx) map that was passed into a Func or View, and for the +[Results](../../guides/developer/iota-chains/schema/how-tos/results.mdx) map that was returned from a call to a Func or View. From 279b054d4c63e9ee23301097b4173e3fe74d2ad7 Mon Sep 17 00:00:00 2001 From: Jeroen van den Hout Date: Tue, 11 Jun 2024 00:59:44 +0200 Subject: [PATCH 19/37] fix(docs): fix or remove broken links --- .../_snippets/iota-chains/EVM-required-prior-knowledge.md | 2 +- .../_snippets/iota-chains/deploy_a_smart_contract.md | 2 +- .../iota-chains/how-tos/token/check_storage_deposit.md | 2 +- .../iota-chains/explanations/smart-contract-anatomy.md | 2 +- .../iota-chains/getting-started/networks-and-chains.mdx | 8 ++++---- .../developer/iota-chains/getting-started/tools.mdx | 8 ++++---- .../how-tos/core-contracts/basics/send-assets-to-l1.mdx | 2 +- .../iota-chains/how-tos/core-contracts/nft/mint-nft.mdx | 2 +- .../how-tos/core-contracts/token/create-foundry.mdx | 2 +- .../how-tos/core-contracts/token/create-native-token.mdx | 2 +- .../how-tos/core-contracts/token/mint-token.mdx | 2 +- .../iota-chains/how-tos/deploy-a-smart-contract.mdx | 4 ++-- .../iota-chains/how-tos/send-funds-from-L1-to-L2.mdx | 2 +- .../developer/iota-chains/how-tos/test-smart-contracts.md | 8 ++++---- .../content/guides/developer/iota-chains/introduction.mdx | 4 ++-- .../guides/developer/iota-chains/schema/introduction.mdx | 2 +- .../developer/iota-chains/solo/how-tos/deploying-sc.md | 2 +- .../operator/iota-chains-node/how-tos/chain-management.md | 2 +- .../guides/operator/iota-chains-node/reference/metrics.md | 2 +- .../references/iota-chains/core-contracts/blocklog.md | 2 +- docs/content/sidebars/developer.js | 4 ++-- 21 files changed, 33 insertions(+), 33 deletions(-) diff --git a/docs/content/_snippets/iota-chains/EVM-required-prior-knowledge.md b/docs/content/_snippets/iota-chains/EVM-required-prior-knowledge.md index 18f71c69ee4..18c3ea9e372 100644 --- a/docs/content/_snippets/iota-chains/EVM-required-prior-knowledge.md +++ b/docs/content/_snippets/iota-chains/EVM-required-prior-knowledge.md @@ -5,7 +5,7 @@ of [tokens](https://en.wikipedia.org/wiki/Cryptocurrency#Crypto_token) in [blockchain](https://en.wikipedia.org/wiki/Blockchain), [Ethereum Request for Comments (ERCs)](https://eips.ethereum.org/erc)(also known as Ethereum Improvement Proposals ( EIP)) -, [NFTs](/learn/protocols/stardust/core-concepts/multi-asset-ledger#non-fungible-tokens-nfts), [Smart Contracts](/learn/smart-contracts/introduction) +, NFTs, Smart Contracts and have already tinkered with [Solidity](https://docs.soliditylang.org/en/v0.8.16/). You should also have basic knowledge on how to [create](../../guides/developer/iota-chains/how-tos/create-a-basic-contract.mdx) and [deploy](../../guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx) diff --git a/docs/content/_snippets/iota-chains/deploy_a_smart_contract.md b/docs/content/_snippets/iota-chains/deploy_a_smart_contract.md index de4579b6d81..7b07b190723 100644 --- a/docs/content/_snippets/iota-chains/deploy_a_smart_contract.md +++ b/docs/content/_snippets/iota-chains/deploy_a_smart_contract.md @@ -1,5 +1,5 @@ :::tip Deploy a Smart Contract -Deploy a Solidity Smart Contract following our [how to Deploy a Smart Contract guide](/isc/how-tos/deploy-a-smart-contract#remix). +Deploy a Solidity Smart Contract following our [how to Deploy a Smart Contract guide](../../guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx#remix). ::: diff --git a/docs/content/_snippets/iota-chains/how-tos/token/check_storage_deposit.md b/docs/content/_snippets/iota-chains/how-tos/token/check_storage_deposit.md index f3b043b7ba5..eca7808a099 100644 --- a/docs/content/_snippets/iota-chains/how-tos/token/check_storage_deposit.md +++ b/docs/content/_snippets/iota-chains/how-tos/token/check_storage_deposit.md @@ -1,6 +1,6 @@ ### 1. Check the Storage Deposit -Check if the amount paid to the contract is the same as the required [storage deposit](/learn/protocols/stardust/core-concepts/storage-deposit) +Check if the amount paid to the contract is the same as the required storage deposit and set the allowance. ```solidity diff --git a/docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md b/docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md index 449263fdc28..e29015879a6 100644 --- a/docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md +++ b/docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md @@ -16,7 +16,7 @@ Smart contracts are programs that are immutably stored in the chain. Through _VM abstraction_, the ISC virtual machine is agnostic about the interpreter used to execute each smart contract. It can support different _VM types_ (i.e., interpreters) simultaneously on the same chain. -For example, it is possible to have [Wasm](../getting-started/languages-and-vms.mdxwasm-vm-for-isc) and [EVM/Solidity](../getting-started/languages-and-vms.mdxevmsolidity-based-smart-contracts) smart +For example, it is possible to have [Wasm](../getting-started/languages-and-vms.mdx#wasm-vm-for-isc) and [EVM/Solidity](../getting-started/languages-and-vms.mdx#evmsolidity-based-smart-contracts) smart contracts coexisting on the same chain. ![Smart Contract Structure](/img/iota-chains/tutorial/SC-structure.png) diff --git a/docs/content/guides/developer/iota-chains/getting-started/networks-and-chains.mdx b/docs/content/guides/developer/iota-chains/getting-started/networks-and-chains.mdx index 1e26373a132..fbae28defc2 100644 --- a/docs/content/guides/developer/iota-chains/getting-started/networks-and-chains.mdx +++ b/docs/content/guides/developer/iota-chains/getting-started/networks-and-chains.mdx @@ -18,7 +18,7 @@ import NetworkInfo from '@theme/NetworkInfo'; [The IOTA EVM Testnet](https://explorer.evm.testnet.iotaledger.net/) runs as a layer 2 on top -of the [IOTA Testnet](/build/networks-endpoints#iota-testnet). This network uses ISC to facilitate +of the IOTA Testnet. This network uses ISC to facilitate an Ethereum Virtual Machine and has an enshrined bridge to layer 1. :::info @@ -52,7 +52,7 @@ The other values (network name and currency symbol) can be whatever value you li [The IOTA EVM Testnet](https://explorer.evm.testnet.iotaledger.net/) runs as a layer 2 on top -of the [IOTA Testnet](/build/networks-endpoints#iota-testnet). This network uses ISC to facilitate +of the IOTA Testnet. This network uses ISC to facilitate :::info @@ -77,7 +77,7 @@ The other values (network name and currency symbol) can be whatever value you li [The ShimmerEVM Testnet](https://explorer.evm.testnet.shimmer.network/) runs as a layer 2 on top -of the [Shimmer Testnet](/build/networks-endpoints#shimmer-testnet). This network uses ISC to facilitate +of the Shimmer Testnet. This network uses ISC to facilitate an Ethereum Virtual Machine and has an enshrined bridge to layer 1. :::info @@ -115,7 +115,7 @@ The other values (network name and currency symbol) can be whatever value you li [The ShimmerEVM Testnet](https://explorer.evm.testnet.shimmer.network/) runs as a layer 2 on top -of the [Shimmer Testnet](/build/networks-endpoints#shimmer-testnet). This network uses ISC to facilitate +of the Shimmer Testnet. This network uses ISC to facilitate an Ethereum Virtual Machine and has an enshrined bridge to layer 1. :::info diff --git a/docs/content/guides/developer/iota-chains/getting-started/tools.mdx b/docs/content/guides/developer/iota-chains/getting-started/tools.mdx index 53566327fd4..ef7bd529a01 100644 --- a/docs/content/guides/developer/iota-chains/getting-started/tools.mdx +++ b/docs/content/guides/developer/iota-chains/getting-started/tools.mdx @@ -75,7 +75,7 @@ The following tools are **only available on IOTA EVM**. ### Blast API -The [Blast API](/build/blastAPI) is a decentralized platform that provides reliable and scalable node infrastructure +The Blast API is a decentralized platform that provides reliable and scalable node infrastructure for accessing blockchain data. You can find the Blast API URLs in the [Network RPCs](#network-rpcs) ### EVM Toolkit @@ -99,13 +99,13 @@ Multisig solution on IOTA EVM. ### Oracles -If your project requires [Oracles](/build/oracles/) to provide data from the outside world, you find both Pyth and Supra have integrated IOTA EVM. +If your project requires Oracles to provide data from the outside world, you find both Pyth and Supra have integrated IOTA EVM. ### Subgraphs -[Subgraphs](/build/subgraphs/) provide a streamlined way for developers to access blockchain data relevant to their applications, +Subgraphs provide a streamlined way for developers to access blockchain data relevant to their applications, significantly enhancing developer efficiency and user experience. IOTA EVM subgraphs available via [Goldsky](https://goldsky.com). ## MetaMask @@ -115,7 +115,7 @@ interact with EVM chains and their applications (dApps). To use your EVM chain with MetaMask, simply open up MetaMask and click on the network drop-down list at the very top. At the bottom of this list, you will see the option `Add network`. On the new page you will see a list of popular network with the option `Add a network manually`. -For example this would be the configs to add our different [EVM chains](/build/networks-endpoints): +For example this would be the configs to add our different EVM chains: diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/send-assets-to-l1.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/send-assets-to-l1.mdx index 7c9278d3647..da6e36c0129 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/send-assets-to-l1.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/send-assets-to-l1.mdx @@ -40,7 +40,7 @@ Then you take the allowance, which will transfer the assets from the caller to t ISC.sandbox.takeAllowedFunds(msg.sender, allowance); ``` -Finally, you can send the assets to the specified L1 address. This will create an output to hold said assets. You can use additional options to add the [timelock](/learn/protocols/stardust/core-concepts/output-unlock-conditions/#timelock) and [expiration](/learn/protocols/stardust/core-concepts/output-unlock-conditions/#expiration) unlock conditions to the output. +Finally, you can send the assets to the specified L1 address. This will create an output to hold said assets. You can use additional options to add the timelock and expiration unlock conditions to the output. ```solidity ISCSendMetadata memory metadata; diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx index b66bd8f15eb..83103c3accb 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx @@ -11,7 +11,7 @@ import ExampleCodeIntro from '../../../../../../_snippets/iota-chains/how-tos/to # Mint an NFT ## About NFTs -The Stardust update allows you to create your own NFTs. You can also use [IRC27](/tips/tips/TIP-0027) for NFTs. This guide will show you how to create an IRC27 L1 NFT using a L2 smart contract. +The Stardust update allows you to create your own NFTs. You can also use [IRC27](https://github.com/iotaledger/tips/blob/main/tips/TIP-0027/tip-0027.md) for NFTs. This guide will show you how to create an IRC27 L1 NFT using a L2 smart contract. ## Example Code diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.mdx index 4c490a2ddb4..b94cb04e099 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.mdx @@ -15,7 +15,7 @@ import ObsoleteTokenCreation from '../../../../../../_snippets/iota-chains/how-t ## About Foundries -The Stardust update allows you to create your own native tokens. Native tokens are minted by a [Foundry](/tips/tips/TIP-0018/#foundry-output). +The Stardust update allows you to create your own native tokens. Native tokens are minted by a [Foundry](https://github.com/iotaledger/tips/blob/main/tips/TIP-0018/tip-0018.md#foundry-output). The Foundry allows you to specify your native token's maximum supply **once** and change the circulating supply. This guide will show you how to create an L1 foundry using a L2 smart contract. diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx index bd099e410b9..85c5c01fa70 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx @@ -18,7 +18,7 @@ This guide will show you how you can efficiently mint new tokens and register th ## About Foundries -The Stardust update allows you to create your own native tokens. Native tokens are minted by a [Foundry](/tips/tips/TIP-0018/#foundry-output). +The Stardust update allows you to create your own native tokens. Native tokens are minted by a [Foundry](https://github.com/iotaledger/tips/blob/main/tips/TIP-0018/tip-0018.md#foundry-output). The Foundry lets you specify your native token's maximum supply **once** and change the circulating supply. ## Example Code diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.mdx index c6671c2682c..f643c908c1c 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.mdx @@ -12,7 +12,7 @@ import ExampleCodeIntro from '../../../../../../_snippets/iota-chains/how-tos/to # Mint Native Tokens -To mint tokens from a [foundry](/tips/tips/TIP-0018/#foundry-output), you first need to be aware that only the foundry owner can mint token, so you should execute the `ISC.accounts.mintNativeTokens` function in the same contract where you also [created the native token](./create-native-token.mdx. +To mint tokens from a [foundry](https://github.com/iotaledger/tips/blob/main/tips/TIP-0018/tip-0018.md#foundry-output), you first need to be aware that only the foundry owner can mint token, so you should execute the `ISC.accounts.mintNativeTokens` function in the same contract where you also [created the native token](./create-native-token.mdx. ## Example Code diff --git a/docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx b/docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx index 2c58738d73d..d18e70ce583 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx @@ -18,7 +18,7 @@ import TabItem from '@theme/TabItem'; # Deploy a Smart Contract -You can deploy your smart contracts to any of your [EVM chains](/build/networks-endpoints/) using popular tools like [Remix](#remix) +You can deploy your smart contracts to any of your EVM chains using popular tools like [Remix](#remix) and [Hardhat](#hardhat). :::tip Get a Basic Contract @@ -41,7 +41,7 @@ Before you get started, make sure you have connected Metamask to your network of :::tip Networks & Endpoints -You can check the connection details in the [Networks & Endpoints section](/build/networks-endpoints/). +You can check the connection details in the Networks & Endpoints section. ::: diff --git a/docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx b/docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx index eb461e2cbc5..48808d45ce7 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx @@ -43,7 +43,7 @@ You can use your [Firefly Wallet](https://firefly.iota.org/) to easily send L1 I #### Requirements -* [IOTA Tokens](/get-started/introduction/iota/iota-token/) or [Shimmer Tokens](/get-started/introduction/shimmer/shimmer-token/) +* IOTA Tokens or Shimmer Tokens * [Firefly Wallet](https://firefly.iota.org/) * [Metamask](https://metamask.io/) diff --git a/docs/content/guides/developer/iota-chains/how-tos/test-smart-contracts.md b/docs/content/guides/developer/iota-chains/how-tos/test-smart-contracts.md index c3f2a8aa344..8153ac3c72c 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/test-smart-contracts.md +++ b/docs/content/guides/developer/iota-chains/how-tos/test-smart-contracts.md @@ -91,8 +91,8 @@ expected. #### Tools -You can use the [EVM Testnet](/build/networks-endpoints/#shimmerevm-testnet) to conduct integration tests without -incurring any fees or the [IOTA Sandbox](/iota-sandbox/getting-started/) if you want to run the tests locally. +You can use the EVM Testnet to conduct integration tests without +incurring any fees or the IOTA Sandbox if you want to run the tests locally. ## Manual Testing @@ -100,9 +100,9 @@ Once you have a complete batch of [automated tests](#automated-testing), manuall behaves as expected in the real world is still good practice. However, to avoid incurring fees or deploying a faulty contract, you can manually test your contract using a sandboxed local network and the EVM Testnet. -Testing using the [IOTA Sandbox](/iota-sandbox/getting-started/) serves well for the first stage of automated and manual +Testing using the IOTA Sandbox serves well for the first stage of automated and manual integration tests, as you have complete control over the entire local network. Once you are confident about how your -contract behaves locally, you can deploy and test on the [EVM Testnet](/build/networks-endpoints/#shimmerevm-testnet), +contract behaves locally, you can deploy and test on the EVM Testnet, which replicates the IOTA EVM and ShimmerEVM networks, but also enables cost and risk-free interactions. diff --git a/docs/content/guides/developer/iota-chains/introduction.mdx b/docs/content/guides/developer/iota-chains/introduction.mdx index 06435430638..e54cf1ddfc8 100644 --- a/docs/content/guides/developer/iota-chains/introduction.mdx +++ b/docs/content/guides/developer/iota-chains/introduction.mdx @@ -46,8 +46,8 @@ _IOTA Smart Contacts multichain architecture._ ## Supported VMs The IOTA Smart Contracts currently -supports [EVM/Solidity](getting-started/languages-and-vms.mdxevmsolidity-based-smart-contracts) -smart contracts, as well as an **experimental** [Wasm VM](getting-started/languages-and-vms.mdxwasm-vm-for-isc). +supports [EVM/Solidity](getting-started/languages-and-vms.mdx#evmsolidity-based-smart-contracts) +smart contracts, as well as an **experimental** [Wasm VM](getting-started/languages-and-vms.mdx#wasm-vm-for-isc). ## Sandbox Interface diff --git a/docs/content/guides/developer/iota-chains/schema/introduction.mdx b/docs/content/guides/developer/iota-chains/schema/introduction.mdx index de35b4c364a..e36ebba7f9c 100644 --- a/docs/content/guides/developer/iota-chains/schema/introduction.mdx +++ b/docs/content/guides/developer/iota-chains/schema/introduction.mdx @@ -33,7 +33,7 @@ The schema tool diminishes redundancy and ensures up-to-date functionalities. The schema definition file serves as a single source of truth, encompassing crucial details like: - State Storage Variables. -- [Funcs and Views](../../explanations/context). +- [Funcs and Views](../explanations/context.mdx). - [Access rights](how-tos/access.mdx). - [Input parameters](how-tos/params.mdx) and [output results](how-tos/results.mdx) . - Additional Data Structures. diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/deploying-sc.md b/docs/content/guides/developer/iota-chains/solo/how-tos/deploying-sc.md index 18088e855c1..8d971d60690 100644 --- a/docs/content/guides/developer/iota-chains/solo/how-tos/deploying-sc.md +++ b/docs/content/guides/developer/iota-chains/solo/how-tos/deploying-sc.md @@ -18,7 +18,7 @@ tags: :::note WASM VM -For more information about how to create Wasm smart contracts, refer to the [Wasm VM chapter](../../getting-started/languages-and-vms.mdxwasm-vm-for-isc). +For more information about how to create Wasm smart contracts, refer to the [Wasm VM chapter](../../getting-started/languages-and-vms.mdx#wasm-vm-for-isc). ::: diff --git a/docs/content/guides/operator/iota-chains-node/how-tos/chain-management.md b/docs/content/guides/operator/iota-chains-node/how-tos/chain-management.md index e59df73e16c..6feb4d92f5c 100644 --- a/docs/content/guides/operator/iota-chains-node/how-tos/chain-management.md +++ b/docs/content/guides/operator/iota-chains-node/how-tos/chain-management.md @@ -56,7 +56,7 @@ This node won't be "officially" recognized by the committee but will still be ab ### Change the Set of Validators -You can do this in different ways, depending on who controls the [governor address](/tips/tips/TIP-0018#alias-output) +You can do this in different ways, depending on who controls the [governor address](https://github.com/iotaledger/tips/blob/main/tips/TIP-0018/tip-0018.md#alias-output) from the alias output of the chain. - If the chain governor address is the chain committee, you can perform the rotation by calling diff --git a/docs/content/guides/operator/iota-chains-node/reference/metrics.md b/docs/content/guides/operator/iota-chains-node/reference/metrics.md index 0e816a696e0..5891b555088 100644 --- a/docs/content/guides/operator/iota-chains-node/reference/metrics.md +++ b/docs/content/guides/operator/iota-chains-node/reference/metrics.md @@ -9,7 +9,7 @@ tags: # Exposed Metrics -Refer to the [testnet endpoints description](/build/networks-endpoints/#shimmerevm-testnet) for access details. +Refer to the testnet endpoints description for access details. | Metric | Description | | ------------------------------------------ | ---------------------------------------------------- | diff --git a/docs/content/references/iota-chains/core-contracts/blocklog.md b/docs/content/references/iota-chains/core-contracts/blocklog.md index c78d57d17a6..c5dbfd15faa 100644 --- a/docs/content/references/iota-chains/core-contracts/blocklog.md +++ b/docs/content/references/iota-chains/core-contracts/blocklog.md @@ -21,7 +21,7 @@ status, receipts, block, and event details. To avoid having a monotonically increasing state size, only the latest `N` blocks (and their events and receipts) are stored. This parameter can be configured -when [deploying the chain](/wasp/how-tos/setting-up-a-chain). +when deploying the chain. --- diff --git a/docs/content/sidebars/developer.js b/docs/content/sidebars/developer.js index e2d3733080e..7c57b435c9c 100644 --- a/docs/content/sidebars/developer.js +++ b/docs/content/sidebars/developer.js @@ -594,9 +594,9 @@ const developer = [ id: 'guides/developer/iota-chains/explanations/how-accounts-work', }, { - type: 'link', + type: 'doc', label: 'Core Contracts', - href: '/isc/reference/core-contracts/overview', + id: 'references/iota-chains/core-contracts/overview', }, ], }, From 7320f1259168a21d421807a73a2896f1070f67d8 Mon Sep 17 00:00:00 2001 From: Jeroen van den Hout Date: Tue, 11 Jun 2024 11:01:03 +0200 Subject: [PATCH 20/37] fix(docs): spelling --- .../how-tos/core-contracts/get-randomness-on-l2.md | 2 +- .../iota-chains/how-tos/core-contracts/introduction.md | 2 +- .../how-tos/core-contracts/token/create-native-token.mdx | 2 +- .../iota-chains/how-tos/send-NFTs-across-chains.md | 2 +- .../guides/developer/iota-chains/schema/how-tos/state.mdx | 6 +++--- .../guides/developer/iota-chains/solo/how-tos/test.mdx | 2 +- .../guides/developer/iota-chains/solo/how-tos/view-sc.md | 2 +- .../references/iota-chains/core-contracts/accounts.md | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/get-randomness-on-l2.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/get-randomness-on-l2.md index 3bf4b3b35e1..9ac2e0032c7 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/get-randomness-on-l2.md +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/get-randomness-on-l2.md @@ -64,7 +64,7 @@ bytes32 nonce = getNonce(); bytes32 digest = keccak256(bytes.concat(entropy, nonce)); ``` -And then repeatidly hash the digest and copy it in a sequence of bytes until you reach the required length. +And then repeatedly hash the digest and copy it in a sequence of bytes until you reach the required length. ```solidity bytes memory value = new bytes(length); diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/introduction.md b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/introduction.md index 9396e8d73ba..0c2fbfd6821 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/introduction.md +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/introduction.md @@ -15,7 +15,7 @@ tags: # The Core Contracts -The [core contracs](../../explanations/core-contracts.md) are contracts deployed on every chain and are vital to interact with L1 and the chain itself. They can be called in Solidity through the [ISC Magic Contract](../../../../../references/iota-chains/magic-contract/introduction.md). +The [core contracts](../../explanations/core-contracts.md) are contracts deployed on every chain and are vital to interact with L1 and the chain itself. They can be called in Solidity through the [ISC Magic Contract](../../../../../references/iota-chains/magic-contract/introduction.md). ## The ISC Magic Contract diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx index 85c5c01fa70..4c97022dd16 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx +++ b/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx @@ -1,5 +1,5 @@ --- -description: How to Create a Native Token Foundary. +description: How to Create a Native Token Foundry. image: /img/logo/WASP_logo_dark.png tags: - foundry diff --git a/docs/content/guides/developer/iota-chains/how-tos/send-NFTs-across-chains.md b/docs/content/guides/developer/iota-chains/how-tos/send-NFTs-across-chains.md index 273c11009b4..504a061c6b4 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/send-NFTs-across-chains.md +++ b/docs/content/guides/developer/iota-chains/how-tos/send-NFTs-across-chains.md @@ -127,7 +127,7 @@ approve step is also required, but the operations will happen on the `ONFT` cont - You can use the [LayerZero Repository](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/libs/LzLib.sol#L44) as a reference to set gas drop on the destination in `adapterParams`. - The provided gas drop must be `<=` the config one. Otherwise, you will get [`dstNativeAmt` too large](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/mocks/LZEndpointMock.sol#L413) error. -- You can use the [LayerZero Repository](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/libs/LzLib.sol#L34) as a refernce to set default `adapterParams` without needing a gas drop. +- You can use the [LayerZero Repository](https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/lzApp/libs/LzLib.sol#L34) as a reference to set default `adapterParams` without needing a gas drop. ##### LayerZero diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/state.mdx b/docs/content/guides/developer/iota-chains/schema/how-tos/state.mdx index 4a8d2e4d425..9bbae269b95 100644 --- a/docs/content/guides/developer/iota-chains/schema/how-tos/state.mdx +++ b/docs/content/guides/developer/iota-chains/schema/how-tos/state.mdx @@ -60,10 +60,10 @@ These represent predefined [WasmLib value types](../../../../../references/iota- ### Arrays and Maps Next, the `memberList` variable denoted by empty brackets `[]`, symbolizing an array. -This array accommodates elements of a homogenous predefined Address value type. +This array accommodates elements of a homogeneous predefined Address value type. Lastly, the `members` variable, signified as a map with `map[]`, houses keys of a uniform predefined Address type. -Following the brackets, the homogenous value type, here `Uint64`, is mentioned. +Following the brackets, the homogeneous value type, here `Uint64`, is mentioned. @@ -182,6 +182,6 @@ Note the generated proxy interface named `MutableDividendState` for mutable `div It enables type-safe proxy object access for each corresponding variable. Moreover, the tool auto-generates intermediate map and array proxy types, such as `ArrayOfMutableAddress` and `MapAddressToMutableUint64`, -enforcing the utilization of respective homogenous types. +enforcing the utilization of respective homogeneous types. See the full `state.xx` for more details. diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/test.mdx b/docs/content/guides/developer/iota-chains/solo/how-tos/test.mdx index d3ea808bd32..f6d0cd5b4b5 100644 --- a/docs/content/guides/developer/iota-chains/solo/how-tos/test.mdx +++ b/docs/content/guides/developer/iota-chains/solo/how-tos/test.mdx @@ -23,7 +23,7 @@ functionalities without the overhead of having to start nodes, set up a committe send transactions over the _Tangle_. Instead, you can use Go's built-in test environment in combination with Solo to deploy chains and smart contracts and simulate transactions. -Solo directly interacts with the ISC code, and therfore uses all the ISC-specific data +Solo directly interacts with the ISC code, and therefore uses all the ISC-specific data types directly. Our Wasm smart contracts cannot access these types directly, because they run in a separate, sandboxed environment. Therefore, WasmLib implements its [own versions](../../../../../references/iota-chains/wasm-lib-data-types.mdx) of these data types, and the _VM_ layer acts as a data type diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/view-sc.md b/docs/content/guides/developer/iota-chains/solo/how-tos/view-sc.md index 7b61257759b..dfe8ab10a9b 100644 --- a/docs/content/guides/developer/iota-chains/solo/how-tos/view-sc.md +++ b/docs/content/guides/developer/iota-chains/solo/how-tos/view-sc.md @@ -29,7 +29,7 @@ that calling a view does not constitute an asynchronous transaction; it is just entry point exposed by the smart contract. Therefore, calling a view does not involve any token transfers. Sending a request (either on-ledger or off-ledger) to a -view entry point will result in an exception, returning all attached tokens to the sender minus fees (iif any). +view entry point will result in an exception, returning all attached tokens to the sender minus fees (if any). Views are used to retrieve information about the smart contract's state, for example, to display on a website. Certain Solo methods such as `chain.GetInfo`, `chain.GetGasFeePolicy`, and `chain.L2Assets` call views of diff --git a/docs/content/references/iota-chains/core-contracts/accounts.md b/docs/content/references/iota-chains/core-contracts/accounts.md index db984f9d793..3f40ce25f79 100644 --- a/docs/content/references/iota-chains/core-contracts/accounts.md +++ b/docs/content/references/iota-chains/core-contracts/accounts.md @@ -339,7 +339,7 @@ Returns the NFTID `z` for a given MintID `D`. #### Parameters -- `D` (`MintID`): MintID producted at the time the NFT was minted +- `D` (`MintID`): MintID produced at the time the NFT was minted #### Returns From 617905b8ebd55ae484d57d9e715c0dee4a06c356 Mon Sep 17 00:00:00 2001 From: Jeroen van den Hout Date: Mon, 15 Jul 2024 12:11:13 +0200 Subject: [PATCH 21/37] refactor(docs): adopt new structure --- .../iota-chains/EVM_compatibility.md | 7 - .../_snippets/iota-chains/about-accounts.md | 5 - .../how-tos/token/obsolete_token_creation.md | 5 - .../EVM-required-prior-knowledge.md | 2 +- .../_snippets/iota-evm/EVM_compatibility.md | 7 + .../_snippets/iota-evm/about-accounts.md | 5 + .../deploy_a_smart_contract.md | 2 +- .../hardhat_config.mdx | 0 .../how-tos/token/check_storage_deposit.md | 0 .../how-tos/token/example_code_intro.mdx | 0 .../how-tos/token/obsolete_token_creation.md | 5 + .../metamask_buttons.mdx | 0 .../on_off_ledger_request.md | 0 .../oracles_contract_data.mdx | 0 .../{iota-chains => iota-evm}/ownership.md | 0 .../{iota-chains => iota-evm}/payable.md | 0 .../{iota-chains => iota-evm}/remix-IDE.md | 0 .../iota-evm}/explanations/consensus.md | 0 .../iota-evm}/explanations/context.mdx | 0 .../iota-evm/explanations/core-contracts.md | 37 +++++ .../explanations/how-accounts-work.md | 6 +- .../iota-evm}/explanations/invocation.mdx | 4 +- .../iota-evm}/explanations/sandbox.md | 4 +- .../explanations/smart-contract-anatomy.md | 8 +- .../iota-evm}/explanations/smart-contracts.md | 0 .../iota-evm}/explanations/state_manager.md | 0 .../iota-evm}/explanations/states.md | 6 +- .../iota-evm}/explanations/validators.md | 2 +- .../getting-started/compatibility.md | 2 +- .../getting-started/languages-and-vms.mdx | 8 +- .../getting-started/networks-and-chains.mdx | 4 +- .../iota-evm}/getting-started/quick-start.mdx | 4 +- .../iota-evm}/getting-started/tools.mdx | 10 +- .../iota-evm}/how-tos/ERC20.mdx | 12 +- .../iota-evm}/how-tos/ERC721.mdx | 14 +- .../core-contracts/basics/allowance/allow.md | 0 .../basics/allowance/get-allowance.md | 0 .../basics/allowance/take-allowance.md | 0 .../core-contracts/basics/get-balance.md | 0 .../basics/send-assets-to-l1.mdx | 2 +- .../how-tos/core-contracts/call-view.md | 6 +- .../core-contracts/get-randomness-on-l2.md | 0 .../how-tos/core-contracts/introduction.md | 8 +- .../core-contracts/nft/introduction.mdx | 0 .../how-tos/core-contracts/nft/mint-nft.mdx | 8 +- .../core-contracts/nft/use-as-erc721.md | 0 .../core-contracts/token/create-foundry.mdx | 4 +- .../token/create-native-token.mdx | 8 +- .../token/erc20-native-token.md | 0 .../core-contracts/token/introduction.mdx | 0 .../core-contracts/token/mint-token.mdx | 2 +- .../core-contracts/token/register-token.mdx | 4 +- .../how-tos/create-a-basic-contract.mdx | 2 +- .../how-tos/deploy-a-smart-contract.mdx | 6 +- .../iota-evm}/how-tos/introduction.md | 0 .../how-tos/send-ERC20-across-chains.md | 0 .../how-tos/send-NFTs-across-chains.md | 0 .../how-tos/send-funds-from-L1-to-L2.mdx | 22 +-- .../iota-evm}/how-tos/test-smart-contracts.md | 0 .../iota-evm}/introduction.mdx | 6 +- .../iota-evm}/schema/how-tos/access.mdx | 0 .../iota-evm}/schema/how-tos/call.mdx | 0 .../iota-evm}/schema/how-tos/events.mdx | 0 .../iota-evm}/schema/how-tos/funcdesc.mdx | 0 .../iota-evm}/schema/how-tos/funcs.mdx | 0 .../iota-evm}/schema/how-tos/init.mdx | 0 .../iota-evm}/schema/how-tos/params.mdx | 0 .../iota-evm}/schema/how-tos/post.mdx | 0 .../iota-evm}/schema/how-tos/results.mdx | 0 .../iota-evm}/schema/how-tos/spec.mdx | 0 .../iota-evm}/schema/how-tos/state.mdx | 2 +- .../iota-evm}/schema/how-tos/structs.mdx | 0 .../iota-evm}/schema/how-tos/thunks.mdx | 0 .../iota-evm}/schema/how-tos/transfers.mdx | 0 .../iota-evm}/schema/how-tos/typedefs.mdx | 2 +- .../iota-evm}/schema/how-tos/usage.mdx | 0 .../iota-evm}/schema/how-tos/views.mdx | 0 .../iota-evm}/schema/how-tos/yaml.mdx | 0 .../iota-evm}/schema/introduction.mdx | 0 .../iota-evm}/schema/proxies.mdx | 4 +- .../iota-evm}/solo/getting-started.md | 0 .../iota-evm}/solo/how-tos/deploying-sc.md | 2 +- .../iota-evm}/solo/how-tos/error-handling.md | 2 +- .../iota-evm}/solo/how-tos/examples.mdx | 0 .../iota-evm}/solo/how-tos/first-example.md | 6 +- .../iota-evm}/solo/how-tos/invoking-sc.md | 4 +- .../iota-evm}/solo/how-tos/test.mdx | 2 +- .../iota-evm}/solo/how-tos/the-l1-ledger.md | 0 .../iota-evm}/solo/how-tos/the-l2-ledger.md | 6 +- .../iota-evm}/solo/how-tos/timelock.mdx | 0 .../iota-evm}/solo/how-tos/view-sc.md | 6 +- .../explanations/core-contracts.md | 37 ----- .../iota-evm}/how-tos/chain-management.md | 2 +- .../iota-evm}/how-tos/running-a-node.md | 0 .../how-tos/running-an-access-node.mdx | 0 .../iota-evm}/how-tos/setting-up-a-chain.md | 4 +- .../iota-evm}/how-tos/wasp-cli.md | 0 .../iota-evm}/reference/configuration.md | 0 .../iota-evm}/reference/metrics.md | 0 .../{iota-chains => iota-evm}/.gitignore | 0 .../core-contracts/accounts.md | 2 +- .../core-contracts/blob.md | 0 .../core-contracts/blocklog.md | 0 .../core-contracts/errors.md | 0 .../core-contracts/evm.md | 4 +- .../core-contracts/governance.md | 0 .../core-contracts/overview.md | 0 .../core-contracts/root.md | 0 .../core-contracts/xfer.md | 0 .../json-rpc-spec.md | 0 .../magic-contract/introduction.md | 0 .../wasm-lib-data-types.mdx | 12 +- docs/content/sidebars/developer.js | 144 +++++++++--------- docs/content/sidebars/operator.js | 18 +-- docs/content/sidebars/references.js | 26 ++-- docs/site/package.json | 4 +- ...ferences.sh => get-iota-evm-references.sh} | 4 +- .../img/{iota-chains => iota-evm}/chain0.png | Bin .../img/{iota-chains => iota-evm}/chain1.png | Bin .../evm/examples/compile.png | Bin .../evm/examples/deploy-metamask.png | Bin .../evm/examples/deploy.png | Bin .../evm/examples/erc20-balance.png | Bin .../examples/explorer-contract-address.png | Bin .../how-tos/ERC20/metamask-erc20-balance.png | Bin ...et-transaction-or-go-to-block-explorer.png | Bin .../how-tos/ERC20/metamask-import-tokens.png | Bin .../how-tos/ERC721/confirm-in-metamask.png | Bin .../evm/how-tos/ERC721/safe-mint.png | Bin .../evm/how-tos/ERC721/set-initial-owner.png | Bin .../get-funds/bloom/bloom-click-on-send.png | Bin .../bloom/bloom-review-and-confirm.png | Bin .../bloom/bloom-select-evm-account-1.png | Bin .../bloom/bloom-select-the-desired-amount.png | Bin .../get-funds/bloom/enter-the-amount.png | Bin .../bloom/enter-the-recipient-address.png | Bin .../review-and-confirm-the-transaction.png | Bin .../how-tos/get-funds/bloom/select-send.png | Bin .../get-funds/bloom/select-the-smr-token.png | Bin .../how-tos/get-funds/copy-your-address.png | Bin ...ur-desired-amount-and-metamask-address.png | Bin .../how-tos/get-funds/firefly/hit-send.png | Bin .../get-funds/firefly/select-send-assets.png | Bin .../get-funds/firefly/select-shimmer-evm.png | Bin .../evm/remix-deployed.png | Bin .../evm/remix-injected-provider-metamask.png | Bin .../evm/remix-injected-provider-set.png | Bin .../evm/remix-metamask-detail.png | Bin .../evm/remix-vm-injected.png | Bin .../{iota-chains => iota-evm}/multichain.png | Bin .../img/{iota-chains => iota-evm}/sandbox.png | Bin .../tutorial/SC-structure.png | Bin .../tutorial/accounts.png | Bin .../tutorial/call_view.png | Bin .../tutorial/send_request.png | Bin .../wasm_vm/IscHost.png | Bin .../wasm_vm/Proxies.png | Bin .../wasm_vm/WasmVM.png | Bin 158 files changed, 265 insertions(+), 265 deletions(-) delete mode 100644 docs/content/_snippets/iota-chains/EVM_compatibility.md delete mode 100644 docs/content/_snippets/iota-chains/about-accounts.md delete mode 100644 docs/content/_snippets/iota-chains/how-tos/token/obsolete_token_creation.md rename docs/content/_snippets/{iota-chains => iota-evm}/EVM-required-prior-knowledge.md (68%) create mode 100644 docs/content/_snippets/iota-evm/EVM_compatibility.md create mode 100644 docs/content/_snippets/iota-evm/about-accounts.md rename docs/content/_snippets/{iota-chains => iota-evm}/deploy_a_smart_contract.md (50%) rename docs/content/_snippets/{iota-chains => iota-evm}/hardhat_config.mdx (100%) rename docs/content/_snippets/{iota-chains => iota-evm}/how-tos/token/check_storage_deposit.md (100%) rename docs/content/_snippets/{iota-chains => iota-evm}/how-tos/token/example_code_intro.mdx (100%) create mode 100644 docs/content/_snippets/iota-evm/how-tos/token/obsolete_token_creation.md rename docs/content/_snippets/{iota-chains => iota-evm}/metamask_buttons.mdx (100%) rename docs/content/_snippets/{iota-chains => iota-evm}/on_off_ledger_request.md (100%) rename docs/content/_snippets/{iota-chains => iota-evm}/oracles_contract_data.mdx (100%) rename docs/content/_snippets/{iota-chains => iota-evm}/ownership.md (100%) rename docs/content/_snippets/{iota-chains => iota-evm}/payable.md (100%) rename docs/content/_snippets/{iota-chains => iota-evm}/remix-IDE.md (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/explanations/consensus.md (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/explanations/context.mdx (100%) create mode 100644 docs/content/developer/iota-evm/explanations/core-contracts.md rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/explanations/how-accounts-work.md (93%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/explanations/invocation.mdx (96%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/explanations/sandbox.md (96%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/explanations/smart-contract-anatomy.md (92%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/explanations/smart-contracts.md (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/explanations/state_manager.md (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/explanations/states.md (97%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/explanations/validators.md (95%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/getting-started/compatibility.md (92%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/getting-started/languages-and-vms.mdx (92%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/getting-started/networks-and-chains.mdx (94%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/getting-started/quick-start.mdx (93%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/getting-started/tools.mdx (94%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/ERC20.mdx (82%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/ERC721.mdx (88%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/core-contracts/basics/allowance/allow.md (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/core-contracts/basics/allowance/get-allowance.md (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/core-contracts/basics/allowance/take-allowance.md (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/core-contracts/basics/get-balance.md (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/core-contracts/basics/send-assets-to-l1.mdx (96%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/core-contracts/call-view.md (67%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/core-contracts/get-randomness-on-l2.md (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/core-contracts/introduction.md (78%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/core-contracts/nft/introduction.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/core-contracts/nft/mint-nft.mdx (89%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/core-contracts/nft/use-as-erc721.md (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/core-contracts/token/create-foundry.mdx (92%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/core-contracts/token/create-native-token.mdx (79%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/core-contracts/token/erc20-native-token.md (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/core-contracts/token/introduction.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/core-contracts/token/mint-token.mdx (92%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/core-contracts/token/register-token.mdx (90%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/create-a-basic-contract.mdx (93%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/deploy-a-smart-contract.mdx (96%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/introduction.md (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/send-ERC20-across-chains.md (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/send-NFTs-across-chains.md (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/send-funds-from-L1-to-L2.mdx (72%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/how-tos/test-smart-contracts.md (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/introduction.mdx (93%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/schema/how-tos/access.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/schema/how-tos/call.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/schema/how-tos/events.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/schema/how-tos/funcdesc.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/schema/how-tos/funcs.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/schema/how-tos/init.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/schema/how-tos/params.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/schema/how-tos/post.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/schema/how-tos/results.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/schema/how-tos/spec.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/schema/how-tos/state.mdx (99%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/schema/how-tos/structs.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/schema/how-tos/thunks.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/schema/how-tos/transfers.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/schema/how-tos/typedefs.mdx (99%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/schema/how-tos/usage.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/schema/how-tos/views.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/schema/how-tos/yaml.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/schema/introduction.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/schema/proxies.mdx (97%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/solo/getting-started.md (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/solo/how-tos/deploying-sc.md (97%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/solo/how-tos/error-handling.md (96%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/solo/how-tos/examples.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/solo/how-tos/first-example.md (93%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/solo/how-tos/invoking-sc.md (97%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/solo/how-tos/test.mdx (97%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/solo/how-tos/the-l1-ledger.md (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/solo/how-tos/the-l2-ledger.md (96%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/solo/how-tos/timelock.mdx (100%) rename docs/content/{guides/developer/iota-chains => developer/iota-evm}/solo/how-tos/view-sc.md (90%) delete mode 100644 docs/content/guides/developer/iota-chains/explanations/core-contracts.md rename docs/content/{guides/operator/iota-chains-node => operator/iota-evm}/how-tos/chain-management.md (96%) rename docs/content/{guides/operator/iota-chains-node => operator/iota-evm}/how-tos/running-a-node.md (100%) rename docs/content/{guides/operator/iota-chains-node => operator/iota-evm}/how-tos/running-an-access-node.mdx (100%) rename docs/content/{guides/operator/iota-chains-node => operator/iota-evm}/how-tos/setting-up-a-chain.md (96%) rename docs/content/{guides/operator/iota-chains-node => operator/iota-evm}/how-tos/wasp-cli.md (100%) rename docs/content/{guides/operator/iota-chains-node => operator/iota-evm}/reference/configuration.md (100%) rename docs/content/{guides/operator/iota-chains-node => operator/iota-evm}/reference/metrics.md (100%) rename docs/content/references/{iota-chains => iota-evm}/.gitignore (100%) rename docs/content/references/{iota-chains => iota-evm}/core-contracts/accounts.md (99%) rename docs/content/references/{iota-chains => iota-evm}/core-contracts/blob.md (100%) rename docs/content/references/{iota-chains => iota-evm}/core-contracts/blocklog.md (100%) rename docs/content/references/{iota-chains => iota-evm}/core-contracts/errors.md (100%) rename docs/content/references/{iota-chains => iota-evm}/core-contracts/evm.md (96%) rename docs/content/references/{iota-chains => iota-evm}/core-contracts/governance.md (100%) rename docs/content/references/{iota-chains => iota-evm}/core-contracts/overview.md (100%) rename docs/content/references/{iota-chains => iota-evm}/core-contracts/root.md (100%) rename docs/content/references/{iota-chains => iota-evm}/core-contracts/xfer.md (100%) rename docs/content/references/{iota-chains => iota-evm}/json-rpc-spec.md (100%) rename docs/content/references/{iota-chains => iota-evm}/magic-contract/introduction.md (100%) rename docs/content/references/{iota-chains => iota-evm}/wasm-lib-data-types.mdx (87%) rename docs/site/scripts/{get-iota-chains-references.sh => get-iota-evm-references.sh} (72%) rename docs/site/static/img/{iota-chains => iota-evm}/chain0.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/chain1.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/examples/compile.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/examples/deploy-metamask.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/examples/deploy.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/examples/erc20-balance.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/examples/explorer-contract-address.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/how-tos/ERC20/metamask-erc20-balance.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/how-tos/ERC20/metamask-get-transaction-or-go-to-block-explorer.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/how-tos/ERC20/metamask-import-tokens.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/how-tos/ERC721/confirm-in-metamask.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/how-tos/ERC721/safe-mint.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/how-tos/ERC721/set-initial-owner.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/how-tos/get-funds/bloom/bloom-click-on-send.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/how-tos/get-funds/bloom/bloom-review-and-confirm.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/how-tos/get-funds/bloom/bloom-select-evm-account-1.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/how-tos/get-funds/bloom/bloom-select-the-desired-amount.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/how-tos/get-funds/bloom/enter-the-amount.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/how-tos/get-funds/bloom/enter-the-recipient-address.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/how-tos/get-funds/bloom/review-and-confirm-the-transaction.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/how-tos/get-funds/bloom/select-send.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/how-tos/get-funds/bloom/select-the-smr-token.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/how-tos/get-funds/copy-your-address.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/how-tos/get-funds/firefly/enter-your-desired-amount-and-metamask-address.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/how-tos/get-funds/firefly/hit-send.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/how-tos/get-funds/firefly/select-send-assets.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/how-tos/get-funds/firefly/select-shimmer-evm.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/remix-deployed.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/remix-injected-provider-metamask.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/remix-injected-provider-set.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/remix-metamask-detail.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/evm/remix-vm-injected.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/multichain.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/sandbox.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/tutorial/SC-structure.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/tutorial/accounts.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/tutorial/call_view.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/tutorial/send_request.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/wasm_vm/IscHost.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/wasm_vm/Proxies.png (100%) rename docs/site/static/img/{iota-chains => iota-evm}/wasm_vm/WasmVM.png (100%) diff --git a/docs/content/_snippets/iota-chains/EVM_compatibility.md b/docs/content/_snippets/iota-chains/EVM_compatibility.md deleted file mode 100644 index cc795c81634..00000000000 --- a/docs/content/_snippets/iota-chains/EVM_compatibility.md +++ /dev/null @@ -1,7 +0,0 @@ -:::info EVM Compatibility - -The ISC EVM layer is also designed to be as compatible as possible with existing Ethereum -[tools](../../guides/developer/iota-chains/getting-started/tools.mdx) and functionalities. However, please make sure you have checked out the current -[properties and limitations](../../guides/developer/iota-chains/getting-started/compatibility.md). - -::: \ No newline at end of file diff --git a/docs/content/_snippets/iota-chains/about-accounts.md b/docs/content/_snippets/iota-chains/about-accounts.md deleted file mode 100644 index aa3b44942eb..00000000000 --- a/docs/content/_snippets/iota-chains/about-accounts.md +++ /dev/null @@ -1,5 +0,0 @@ -:::info Accounts in ISC - -Learn more about the [different types of accounts](../../guides/developer/iota-chains/explanations/how-accounts-work.md). - -::: \ No newline at end of file diff --git a/docs/content/_snippets/iota-chains/how-tos/token/obsolete_token_creation.md b/docs/content/_snippets/iota-chains/how-tos/token/obsolete_token_creation.md deleted file mode 100644 index ae8b77287db..00000000000 --- a/docs/content/_snippets/iota-chains/how-tos/token/obsolete_token_creation.md +++ /dev/null @@ -1,5 +0,0 @@ -:::caution - -This method is now obsolete, use the new [`createNativeTokenFoundry`](../../../../guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx) method instead. - -::: \ No newline at end of file diff --git a/docs/content/_snippets/iota-chains/EVM-required-prior-knowledge.md b/docs/content/_snippets/iota-evm/EVM-required-prior-knowledge.md similarity index 68% rename from docs/content/_snippets/iota-chains/EVM-required-prior-knowledge.md rename to docs/content/_snippets/iota-evm/EVM-required-prior-knowledge.md index 18c3ea9e372..1f944123c14 100644 --- a/docs/content/_snippets/iota-chains/EVM-required-prior-knowledge.md +++ b/docs/content/_snippets/iota-evm/EVM-required-prior-knowledge.md @@ -8,7 +8,7 @@ EIP)) , NFTs, Smart Contracts and have already tinkered with [Solidity](https://docs.soliditylang.org/en/v0.8.16/). -You should also have basic knowledge on how to [create](../../guides/developer/iota-chains/how-tos/create-a-basic-contract.mdx) and [deploy](../../guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx) +You should also have basic knowledge on how to [create](../../developer/iota-evm/how-tos/create-a-basic-contract.mdx) and [deploy](../../developer/iota-evm/how-tos/deploy-a-smart-contract.mdx) a smart contract. ::: \ No newline at end of file diff --git a/docs/content/_snippets/iota-evm/EVM_compatibility.md b/docs/content/_snippets/iota-evm/EVM_compatibility.md new file mode 100644 index 00000000000..99714181392 --- /dev/null +++ b/docs/content/_snippets/iota-evm/EVM_compatibility.md @@ -0,0 +1,7 @@ +:::info EVM Compatibility + +The ISC EVM layer is also designed to be as compatible as possible with existing Ethereum +[tools](../../developer/iota-evm/getting-started/tools.mdx) and functionalities. However, please make sure you have checked out the current +[properties and limitations](../../developer/iota-evm/getting-started/compatibility.md). + +::: \ No newline at end of file diff --git a/docs/content/_snippets/iota-evm/about-accounts.md b/docs/content/_snippets/iota-evm/about-accounts.md new file mode 100644 index 00000000000..0763f491746 --- /dev/null +++ b/docs/content/_snippets/iota-evm/about-accounts.md @@ -0,0 +1,5 @@ +:::info Accounts in ISC + +Learn more about the [different types of accounts](../../developer/iota-evm/explanations/how-accounts-work.md). + +::: \ No newline at end of file diff --git a/docs/content/_snippets/iota-chains/deploy_a_smart_contract.md b/docs/content/_snippets/iota-evm/deploy_a_smart_contract.md similarity index 50% rename from docs/content/_snippets/iota-chains/deploy_a_smart_contract.md rename to docs/content/_snippets/iota-evm/deploy_a_smart_contract.md index 7b07b190723..94cbdacf259 100644 --- a/docs/content/_snippets/iota-chains/deploy_a_smart_contract.md +++ b/docs/content/_snippets/iota-evm/deploy_a_smart_contract.md @@ -1,5 +1,5 @@ :::tip Deploy a Smart Contract -Deploy a Solidity Smart Contract following our [how to Deploy a Smart Contract guide](../../guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx#remix). +Deploy a Solidity Smart Contract following our [how to Deploy a Smart Contract guide](../../developer/iota-evm/how-tos/deploy-a-smart-contract.mdx#remix). ::: diff --git a/docs/content/_snippets/iota-chains/hardhat_config.mdx b/docs/content/_snippets/iota-evm/hardhat_config.mdx similarity index 100% rename from docs/content/_snippets/iota-chains/hardhat_config.mdx rename to docs/content/_snippets/iota-evm/hardhat_config.mdx diff --git a/docs/content/_snippets/iota-chains/how-tos/token/check_storage_deposit.md b/docs/content/_snippets/iota-evm/how-tos/token/check_storage_deposit.md similarity index 100% rename from docs/content/_snippets/iota-chains/how-tos/token/check_storage_deposit.md rename to docs/content/_snippets/iota-evm/how-tos/token/check_storage_deposit.md diff --git a/docs/content/_snippets/iota-chains/how-tos/token/example_code_intro.mdx b/docs/content/_snippets/iota-evm/how-tos/token/example_code_intro.mdx similarity index 100% rename from docs/content/_snippets/iota-chains/how-tos/token/example_code_intro.mdx rename to docs/content/_snippets/iota-evm/how-tos/token/example_code_intro.mdx diff --git a/docs/content/_snippets/iota-evm/how-tos/token/obsolete_token_creation.md b/docs/content/_snippets/iota-evm/how-tos/token/obsolete_token_creation.md new file mode 100644 index 00000000000..fd878ea0fca --- /dev/null +++ b/docs/content/_snippets/iota-evm/how-tos/token/obsolete_token_creation.md @@ -0,0 +1,5 @@ +:::caution + +This method is now obsolete, use the new [`createNativeTokenFoundry`](../../../../developer/iota-evm/how-tos/core-contracts/token/create-native-token.mdx) method instead. + +::: \ No newline at end of file diff --git a/docs/content/_snippets/iota-chains/metamask_buttons.mdx b/docs/content/_snippets/iota-evm/metamask_buttons.mdx similarity index 100% rename from docs/content/_snippets/iota-chains/metamask_buttons.mdx rename to docs/content/_snippets/iota-evm/metamask_buttons.mdx diff --git a/docs/content/_snippets/iota-chains/on_off_ledger_request.md b/docs/content/_snippets/iota-evm/on_off_ledger_request.md similarity index 100% rename from docs/content/_snippets/iota-chains/on_off_ledger_request.md rename to docs/content/_snippets/iota-evm/on_off_ledger_request.md diff --git a/docs/content/_snippets/iota-chains/oracles_contract_data.mdx b/docs/content/_snippets/iota-evm/oracles_contract_data.mdx similarity index 100% rename from docs/content/_snippets/iota-chains/oracles_contract_data.mdx rename to docs/content/_snippets/iota-evm/oracles_contract_data.mdx diff --git a/docs/content/_snippets/iota-chains/ownership.md b/docs/content/_snippets/iota-evm/ownership.md similarity index 100% rename from docs/content/_snippets/iota-chains/ownership.md rename to docs/content/_snippets/iota-evm/ownership.md diff --git a/docs/content/_snippets/iota-chains/payable.md b/docs/content/_snippets/iota-evm/payable.md similarity index 100% rename from docs/content/_snippets/iota-chains/payable.md rename to docs/content/_snippets/iota-evm/payable.md diff --git a/docs/content/_snippets/iota-chains/remix-IDE.md b/docs/content/_snippets/iota-evm/remix-IDE.md similarity index 100% rename from docs/content/_snippets/iota-chains/remix-IDE.md rename to docs/content/_snippets/iota-evm/remix-IDE.md diff --git a/docs/content/guides/developer/iota-chains/explanations/consensus.md b/docs/content/developer/iota-evm/explanations/consensus.md similarity index 100% rename from docs/content/guides/developer/iota-chains/explanations/consensus.md rename to docs/content/developer/iota-evm/explanations/consensus.md diff --git a/docs/content/guides/developer/iota-chains/explanations/context.mdx b/docs/content/developer/iota-evm/explanations/context.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/explanations/context.mdx rename to docs/content/developer/iota-evm/explanations/context.mdx diff --git a/docs/content/developer/iota-evm/explanations/core-contracts.md b/docs/content/developer/iota-evm/explanations/core-contracts.md new file mode 100644 index 00000000000..272735574b0 --- /dev/null +++ b/docs/content/developer/iota-evm/explanations/core-contracts.md @@ -0,0 +1,37 @@ +--- +description: There currently are 6 core smart contracts that are always deployed on each chain, root, _default, accounts, blob, blocklog, and governance. +image: /img/banner/banner_wasp_core_contracts_overview.png +tags: + - smart contracts + - core + - initialization + - request handling + - on-chain ledger + - accounts + - data + - receipts + - reference +--- + +# Core Contracts + +![Wasp Node Core Contracts Overview](/img/banner/banner_wasp_core_contracts_overview.png) + +There are currently 7 core smart contracts that are always deployed on each +chain. These are responsible for the vital functions of the chain and +provide infrastructure for all other smart contracts: + +- [`root`](../../../../references/iota-evm/core-contracts/root.md): Responsible for the initialization of the chain, maintains registry of deployed contracts. + +- [`accounts`](../../../../references/iota-evm/core-contracts/accounts.md): Manages the on-chain ledger of accounts. + +- [`blob`](../../../../references/iota-evm/core-contracts/blob.md): Responsible for the registry of binary objects of arbitrary size. + +- [`blocklog`](../../../../references/iota-evm/core-contracts/blocklog.md): Keeps track of the blocks and receipts of requests that were processed by the chain. + +- [`governance`](../../../../references/iota-evm/core-contracts/governance.md): Handles the administrative functions of the chain. For example: rotation of the committee of validators of the chain, fees and other chain-specific configurations. + +- [`errors`](../../../../references/iota-evm/core-contracts/errors.md): Keeps a map of error codes to error messages templates. These error codes are used in request receipts. + +- [`evm`](../../../../references/iota-evm/core-contracts/evm.md): Provides the necessary infrastructure to accept Ethereum + transactions and execute EVM code. diff --git a/docs/content/guides/developer/iota-chains/explanations/how-accounts-work.md b/docs/content/developer/iota-evm/explanations/how-accounts-work.md similarity index 93% rename from docs/content/guides/developer/iota-chains/explanations/how-accounts-work.md rename to docs/content/developer/iota-evm/explanations/how-accounts-work.md index 1f2398d2ded..0155bf39065 100644 --- a/docs/content/guides/developer/iota-chains/explanations/how-accounts-work.md +++ b/docs/content/developer/iota-evm/explanations/how-accounts-work.md @@ -1,7 +1,7 @@ --- description: 'IOTA Smart Contracts chains keep a ledger of on-chain account balances. On-chain accounts are identified by an AgentID.' -image: /img/iota-chains/tutorial/accounts.png +image: /img/iota-evm/tutorial/accounts.png tags: - smart contracts @@ -74,7 +74,7 @@ Tokens in an Ethereum account can only be moved by sending an Ethereum transacti ## The Accounts Contract -The [`accounts` core contract](../../../../references/iota-chains/core-contracts/accounts.md) is responsible for managing the L2 ledger. +The [`accounts` core contract](../../../../references/iota-evm/core-contracts/accounts.md) is responsible for managing the L2 ledger. By calling this contract, it is possible to: - [View current account balances](../how-tos/core-contracts/basics/get-balance.md) @@ -86,7 +86,7 @@ By calling this contract, it is possible to: The following diagram illustrates an example situation. The IDs and hnames are shortened for simplicity. -[![Example situation. Two chains are deployed, with three smart contracts and one address.](/img/iota-chains/tutorial/accounts.png)](/img/iota-chains/tutorial/accounts.png) +[![Example situation. Two chains are deployed, with three smart contracts and one address.](/img/iota-evm/tutorial/accounts.png)](/img/iota-evm/tutorial/accounts.png) Two chains are deployed, with IDs `chainA` and `chainB`. `chainA` has two smart contracts on it (with hnames `3037` and `2225`), and `chainB` has one smart contract (`7003`). diff --git a/docs/content/guides/developer/iota-chains/explanations/invocation.mdx b/docs/content/developer/iota-evm/explanations/invocation.mdx similarity index 96% rename from docs/content/guides/developer/iota-chains/explanations/invocation.mdx rename to docs/content/developer/iota-evm/explanations/invocation.mdx index 9d40696a8bc..de8fc7ff256 100644 --- a/docs/content/guides/developer/iota-chains/explanations/invocation.mdx +++ b/docs/content/developer/iota-evm/explanations/invocation.mdx @@ -14,7 +14,7 @@ tags: --- -import OnOffLedgerRequest from '../../../../_snippets/iota-chains/on_off_ledger_request.md'; +import OnOffLedgerRequest from '../../../../_snippets/iota-evm/on_off_ledger_request.md'; # Calling a Smart Contract @@ -78,7 +78,7 @@ as token swaps can require more due to the higher computational work involved. For users to specify how much they're willing to pay for a request, they need to specify a `GasBudget` in the request. This gas budget is the "maximum operations that this request can execute" and will be charged as a fee based on the -chain's current [fee policy](../../../../references/iota-chains/core-contracts/governance.md#fee-policy). +chain's current [fee policy](../../../../references/iota-evm/core-contracts/governance.md#fee-policy). The funds to cover the gas used will be charged directly from the user's on-chain account. diff --git a/docs/content/guides/developer/iota-chains/explanations/sandbox.md b/docs/content/developer/iota-evm/explanations/sandbox.md similarity index 96% rename from docs/content/guides/developer/iota-chains/explanations/sandbox.md rename to docs/content/developer/iota-evm/explanations/sandbox.md index dffa9648862..1a63b434aea 100644 --- a/docs/content/guides/developer/iota-chains/explanations/sandbox.md +++ b/docs/content/developer/iota-evm/explanations/sandbox.md @@ -1,7 +1,7 @@ --- description: 'Smart Contracts can only interact with the world by using the Sandbox interface which provides limited and deterministic access to the state through a key/value storage abstraction.' -image: /img/iota-chains/sandbox.png +image: /img/iota-evm/sandbox.png tags: - smart contracts @@ -26,7 +26,7 @@ Instead of working on the state as a whole, each smart contract can only modify The only way for smart contracts to access data is to use the sandbox interface, which is deterministic. It provides their internal state as a list of key/value pairs. -![Sandbox](/img/iota-chains/sandbox.png) +![Sandbox](/img/iota-evm/sandbox.png) Besides reading and writing to the contract state, the Sandbox interface allows smart contracts to access: diff --git a/docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md b/docs/content/developer/iota-evm/explanations/smart-contract-anatomy.md similarity index 92% rename from docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md rename to docs/content/developer/iota-evm/explanations/smart-contract-anatomy.md index e29015879a6..2da2952c532 100644 --- a/docs/content/guides/developer/iota-chains/explanations/smart-contract-anatomy.md +++ b/docs/content/developer/iota-evm/explanations/smart-contract-anatomy.md @@ -1,6 +1,6 @@ --- description: Each smart contract instance has a program with a collection of entry points and a state. -image: /img/iota-chains/tutorial/SC-structure.png +image: /img/iota-evm/tutorial/SC-structure.png tags: - smart contracts - structure @@ -19,13 +19,13 @@ It can support different _VM types_ (i.e., interpreters) simultaneously on the s For example, it is possible to have [Wasm](../getting-started/languages-and-vms.mdx#wasm-vm-for-isc) and [EVM/Solidity](../getting-started/languages-and-vms.mdx#evmsolidity-based-smart-contracts) smart contracts coexisting on the same chain. -![Smart Contract Structure](/img/iota-chains/tutorial/SC-structure.png) +![Smart Contract Structure](/img/iota-evm/tutorial/SC-structure.png) ## Identifying a Smart Contract The ISC [core contracts](core-contracts.md) and WASM contracts on the chain are identified by a _hname_ (pronounced "aitch-name"), which is a `uint32` value calculated as a hash of the smart contract's instance name (a string). -For example, the hname of the [`root`](../../../../references/iota-chains/core-contracts/root.md) core contract +For example, the hname of the [`root`](../../../../references/iota-evm/core-contracts/root.md) core contract is `0xcebf5908`. This value uniquely identifies this contract in every chain. This does not apply to EVM contracts. ## State @@ -65,7 +65,7 @@ There are two types of entry points: ## Execution Results After a request to a Smart Contract is executed (a call to a full entry point), a _receipt_ will be added to -the [`blocklog`](../../../../references/iota-chains/core-contracts/blocklog.md) core contract. The receipt details the +the [`blocklog`](../../../../references/iota-evm/core-contracts/blocklog.md) core contract. The receipt details the execution results of said request: whether it was successful, the block it was included in, and other information. Any events dispatched by the smart contract in context of this execution will also be added to the receipt. diff --git a/docs/content/guides/developer/iota-chains/explanations/smart-contracts.md b/docs/content/developer/iota-evm/explanations/smart-contracts.md similarity index 100% rename from docs/content/guides/developer/iota-chains/explanations/smart-contracts.md rename to docs/content/developer/iota-evm/explanations/smart-contracts.md diff --git a/docs/content/guides/developer/iota-chains/explanations/state_manager.md b/docs/content/developer/iota-evm/explanations/state_manager.md similarity index 100% rename from docs/content/guides/developer/iota-chains/explanations/state_manager.md rename to docs/content/developer/iota-evm/explanations/state_manager.md diff --git a/docs/content/guides/developer/iota-chains/explanations/states.md b/docs/content/developer/iota-evm/explanations/states.md similarity index 97% rename from docs/content/guides/developer/iota-chains/explanations/states.md rename to docs/content/developer/iota-evm/explanations/states.md index d44deacc87f..8608432fcf0 100644 --- a/docs/content/guides/developer/iota-chains/explanations/states.md +++ b/docs/content/developer/iota-evm/explanations/states.md @@ -1,7 +1,7 @@ --- description: 'The state of the chain consists of balances of native IOTA digital assets and a collection of key/value pairs which represents use case-specific data stored in the chain by its smart contracts outside the UTXO ledger.' -image: /img/iota-chains/chain0.png +image: /img/iota-evm/chain0.png tags: - state @@ -107,7 +107,7 @@ produces the next one. The transaction includes the movement of the chain's asse At any moment in time, the data state of the chain is a result of applying the historical sequence of blocks, starting from the empty data state. -![State transitions](/img/iota-chains/chain0.png) +![State transitions](/img/iota-evm/chain0.png) On the L1 UTXO ledger, the state's history is represented as a sequence (chain) of UTXOs, each holding the chain’s assets in a particular state and the anchoring hash of the data state. @@ -119,4 +119,4 @@ state hash). The ISC virtual machine (VM) computes the blocks and state outputs that anchor the state, which ensures that the state transitions are calculated deterministically and consistently. -![Chain](/img/iota-chains/chain1.png) +![Chain](/img/iota-evm/chain1.png) diff --git a/docs/content/guides/developer/iota-chains/explanations/validators.md b/docs/content/developer/iota-evm/explanations/validators.md similarity index 95% rename from docs/content/guides/developer/iota-chains/explanations/validators.md rename to docs/content/developer/iota-evm/explanations/validators.md index 31a3db68939..11be09533be 100644 --- a/docs/content/guides/developer/iota-chains/explanations/validators.md +++ b/docs/content/developer/iota-evm/explanations/validators.md @@ -46,4 +46,4 @@ It is common for validator nodes to be part of a private subnet and have only a outside world, protecting the committee from external attacks. The management of validator and access nodes is done through -the [`governance` core contract](../../../../references/iota-chains/core-contracts/governance.md). +the [`governance` core contract](../../../../references/iota-evm/core-contracts/governance.md). diff --git a/docs/content/guides/developer/iota-chains/getting-started/compatibility.md b/docs/content/developer/iota-evm/getting-started/compatibility.md similarity index 92% rename from docs/content/guides/developer/iota-chains/getting-started/compatibility.md rename to docs/content/developer/iota-evm/getting-started/compatibility.md index 3103f0273fc..30e9a532448 100644 --- a/docs/content/guides/developer/iota-chains/getting-started/compatibility.md +++ b/docs/content/developer/iota-evm/getting-started/compatibility.md @@ -14,7 +14,7 @@ tags: # EVM Compatibility in IOTA Smart Contracts -The [`evm`](../../../../references/iota-chains/core-contracts/evm.md) [core contract](../../../../references/iota-chains/core-contracts/overview.md) +The [`evm`](../../../../references/iota-evm/core-contracts/evm.md) [core contract](../../../../references/iota-evm/core-contracts/overview.md) provides EVM support in IOTA Smart Contracts. It stores the EVM state (account balances, state, code, etc.) and provides a way to execute EVM code to manipulate the state. diff --git a/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.mdx b/docs/content/developer/iota-evm/getting-started/languages-and-vms.mdx similarity index 92% rename from docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.mdx rename to docs/content/developer/iota-evm/getting-started/languages-and-vms.mdx index b316deb450c..5be2c353530 100644 --- a/docs/content/guides/developer/iota-chains/getting-started/languages-and-vms.mdx +++ b/docs/content/developer/iota-evm/getting-started/languages-and-vms.mdx @@ -11,7 +11,7 @@ tags: - reference --- -import EVMCompatibility from '../../../../_snippets/iota-chains/EVM_compatibility.md' +import EVMCompatibility from '../../../../_snippets/iota-evm/EVM_compatibility.md' # Supported Virtual Machines & Languages @@ -37,7 +37,7 @@ changes to function on IOTA Smart Contracts. ### How IOTA Smart Contracts Work With EVM Every deployed ISC chain automatically includes a core contract -called [`evm`](../../../../references/iota-chains/core-contracts/evm.md). This core contract is responsible for running EVM code and +called [`evm`](../../../../references/iota-evm/core-contracts/evm.md). This core contract is responsible for running EVM code and storing the EVM state. The Wasp node also provides a standard JSON-RPC service, which allows you to interact with the EVM layer using existing @@ -60,13 +60,13 @@ IOTA Smart Contracts (ISC) provide a sandboxed environment through an API, facil interactions with ISC functions. This API supports any Virtual Machine (VM) aiming to build a system for smart contract code execution on ISC. -![Wasp node ISC Host](/img/iota-chains/wasm_vm/IscHost.png) +![Wasp node ISC Host](/img/iota-evm/wasm_vm/IscHost.png) You can use a [WebAssembly (Wasm)](https://webassembly.org/) VM as a compilation target, facilitated by the open-source [Wasmtime runtime](https://wasmtime.dev/). This setup encourages dynamic smart contract operations compiled to Wasm code, promoting security and adaptability with different programming languages. -![Wasm VM](/img/iota-chains/wasm_vm/WasmVM.png) +![Wasm VM](/img/iota-evm/wasm_vm/WasmVM.png) The Wasm VM operates with self-contained `WasmLib` libraries linked to individual Wasm codes, optimizing the ISC sandbox functionality and smart contract state storage access. diff --git a/docs/content/guides/developer/iota-chains/getting-started/networks-and-chains.mdx b/docs/content/developer/iota-evm/getting-started/networks-and-chains.mdx similarity index 94% rename from docs/content/guides/developer/iota-chains/getting-started/networks-and-chains.mdx rename to docs/content/developer/iota-evm/getting-started/networks-and-chains.mdx index fbae28defc2..d4d42a67d2d 100644 --- a/docs/content/guides/developer/iota-chains/getting-started/networks-and-chains.mdx +++ b/docs/content/developer/iota-evm/getting-started/networks-and-chains.mdx @@ -139,5 +139,5 @@ The other values (network name and currency symbol) can be whatever value you li ## Core Contracts [IOTA EVM](#IOTAEVM), [ShimmerEVM](#shimmerEVM) and the testnet networks have 7 -[core contracts](../../../../references/iota-chains/core-contracts/overview.md) deployed, as well as the -[Magic Contract](../../../../references/iota-chains/magic-contract/introduction.md). +[core contracts](../../../../references/iota-evm/core-contracts/overview.md) deployed, as well as the +[Magic Contract](../../../../references/iota-evm/magic-contract/introduction.md). diff --git a/docs/content/guides/developer/iota-chains/getting-started/quick-start.mdx b/docs/content/developer/iota-evm/getting-started/quick-start.mdx similarity index 93% rename from docs/content/guides/developer/iota-chains/getting-started/quick-start.mdx rename to docs/content/developer/iota-evm/getting-started/quick-start.mdx index ac206942f93..7a623a318a4 100644 --- a/docs/content/guides/developer/iota-chains/getting-started/quick-start.mdx +++ b/docs/content/developer/iota-evm/getting-started/quick-start.mdx @@ -12,8 +12,8 @@ tags: - JSON - RPC --- -import DeployAdmonition from '../../../../_snippets/iota-chains/deploy_a_smart_contract.md'; -import MetamaskButtons from '../../../../_snippets/iota-chains/metamask_buttons.mdx'; +import DeployAdmonition from '../../../../_snippets/iota-evm/deploy_a_smart_contract.md'; +import MetamaskButtons from '../../../../_snippets/iota-evm/metamask_buttons.mdx'; import { Networks } from '@theme/constant'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; diff --git a/docs/content/guides/developer/iota-chains/getting-started/tools.mdx b/docs/content/developer/iota-evm/getting-started/tools.mdx similarity index 94% rename from docs/content/guides/developer/iota-chains/getting-started/tools.mdx rename to docs/content/developer/iota-evm/getting-started/tools.mdx index ef7bd529a01..ed8a57bd7f1 100644 --- a/docs/content/guides/developer/iota-chains/getting-started/tools.mdx +++ b/docs/content/developer/iota-evm/getting-started/tools.mdx @@ -19,12 +19,12 @@ tags: import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import {AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; -import HardhatConfig from '../../../../_snippets/iota-chains/hardhat_config.mdx'; +import HardhatConfig from '../../../../_snippets/iota-evm/hardhat_config.mdx'; import { Networks } from '@theme/constant'; -import DeployAdmonition from '../../../../_snippets/iota-chains/deploy_a_smart_contract.md'; +import DeployAdmonition from '../../../../_snippets/iota-evm/deploy_a_smart_contract.md'; import { ChainId } from '@theme/ChainId'; import NetworkInfo from '@theme/NetworkInfo'; -import OraclesContractData from '../../../../_snippets/iota-chains/oracles_contract_data.mdx'; +import OraclesContractData from '../../../../_snippets/iota-evm/oracles_contract_data.mdx'; # Compatible Tools @@ -151,14 +151,14 @@ should set the environment as **Injected Provider - Metamask**, which should the Click on the _Deploy & Run transactions_ button in the menu on the left and select `Injected Web3` from the `Environment` dropdown. -![Select Injected Provider from the Environment dropdown](/img/iota-chains/evm/remix-injected-provider-metamask.png) +![Select Injected Provider from the Environment dropdown](/img/iota-evm/evm/remix-injected-provider-metamask.png) Metamask will ask to connect to Remix, and once connected, it will set the `Environment` to `Injected Web3` with the "Custom (Chain ID) network". -![Environment will be set to Injected Web3](/img/iota-chains/evm/remix-injected-provider-set.png)] +![Environment will be set to Injected Web3](/img/iota-evm/evm/remix-injected-provider-set.png)] ## Hardhat diff --git a/docs/content/guides/developer/iota-chains/how-tos/ERC20.mdx b/docs/content/developer/iota-evm/how-tos/ERC20.mdx similarity index 82% rename from docs/content/guides/developer/iota-chains/how-tos/ERC20.mdx rename to docs/content/developer/iota-evm/how-tos/ERC20.mdx index 99cfc64b3d7..cdc49431724 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/ERC20.mdx +++ b/docs/content/developer/iota-evm/how-tos/ERC20.mdx @@ -12,9 +12,9 @@ tags: - how to --- -import DeployAdmonition from '../../../../_snippets/iota-chains/deploy_a_smart_contract.md'; -import PriorKnowledge from '../../../../_snippets/iota-chains/EVM-required-prior-knowledge.md'; -import RemixIDE from '../../../../_snippets/iota-chains/remix-IDE.md'; +import DeployAdmonition from '../../../../_snippets/iota-evm/deploy_a_smart_contract.md'; +import PriorKnowledge from '../../../../_snippets/iota-evm/EVM-required-prior-knowledge.md'; +import RemixIDE from '../../../../_snippets/iota-evm/remix-IDE.md'; # Create ERC20 Custom Tokens @@ -78,17 +78,17 @@ Once you have deployed your contract, you can add your new custom token to your [ShimmerEVM Explorer](https://explorer.evm.testnet.shimmer.network/) or [EVM Testnet Explorer](https://explorer.evm.testnet.shimmer.network/) and use the search bar to find transaction. -!['View on block explorer](/img/iota-chains/evm/how-tos/ERC20/metamask-get-transaction-or-go-to-block-explorer.png) +!['View on block explorer](/img/iota-evm/evm/how-tos/ERC20/metamask-get-transaction-or-go-to-block-explorer.png) 2. Copy the contract address from the transaction details, and import your custom ERC20 tokens into MetaMask. -![Copy contract address](/img/iota-chains/evm/how-tos/ERC20/metamask-import-tokens.png) +![Copy contract address](/img/iota-evm/evm/how-tos/ERC20/metamask-import-tokens.png) ## 3. Have some Fun Now you should see your token in MetaMask. You can send them to your friends without any fees or gas costs. -![Copy contract address](/img/iota-chains/evm/how-tos/ERC20/metamask-erc20-balance.png) +![Copy contract address](/img/iota-evm/evm/how-tos/ERC20/metamask-erc20-balance.png) You also can ask in the [Discord Chat Server](https://discord.iota.org) to send them around and discover what the community is building on IOTA Smart Contracts. diff --git a/docs/content/guides/developer/iota-chains/how-tos/ERC721.mdx b/docs/content/developer/iota-evm/how-tos/ERC721.mdx similarity index 88% rename from docs/content/guides/developer/iota-chains/how-tos/ERC721.mdx rename to docs/content/developer/iota-evm/how-tos/ERC721.mdx index b81b02efdf5..6b3d80000e8 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/ERC721.mdx +++ b/docs/content/developer/iota-evm/how-tos/ERC721.mdx @@ -1,6 +1,6 @@ --- description: Create and deploy a Solidity smart contract to mint NFTs using the ERC721 standard. -image: /img/iota-chains/evm/ozw-721.png +image: /img/iota-evm/evm/ozw-721.png tags: - smart contracts - EVM @@ -11,9 +11,9 @@ tags: - mint tokens - how to --- -import DeployAdmonition from '../../../../_snippets/iota-chains/deploy_a_smart_contract.md'; -import PriorKnowledge from '../../../../_snippets/iota-chains/EVM-required-prior-knowledge.md'; -import RemixIDE from '../../../../_snippets/iota-chains/remix-IDE.md'; +import DeployAdmonition from '../../../../_snippets/iota-evm/deploy_a_smart_contract.md'; +import PriorKnowledge from '../../../../_snippets/iota-evm/EVM-required-prior-knowledge.md'; +import RemixIDE from '../../../../_snippets/iota-evm/remix-IDE.md'; # Create ERC721 NFTs @@ -103,7 +103,7 @@ directly. Before you can deploy this contract, you will need to set the `Initial Owner` address; this can be your own IOTA EVM address. -!["Set the initial owner" img.png](/img/iota-chains/evm/how-tos/ERC721/set-initial-owner.png) +!["Set the initial owner" img.png](/img/iota-evm/evm/how-tos/ERC721/set-initial-owner.png) ::: @@ -117,11 +117,11 @@ To do, you should: 1. Open the contract (listed under `Deployed Contracts`). 2. Insert your target IOTA EVM in beside the `safeMint` button and then click the button. - ![Safe mint](/img/iota-chains/evm/how-tos/ERC721/safe-mint.png) + ![Safe mint](/img/iota-evm/evm/how-tos/ERC721/safe-mint.png) 3. Confirm the transaction on Metamask. - ![Confirm in metamask](/img/iota-chains/evm/how-tos/ERC721/confirm-in-metamask.png) + ![Confirm in metamask](/img/iota-evm/evm/how-tos/ERC721/confirm-in-metamask.png) If you visit your address in the visit the [IOTA EVM Explorer](https://explorer.evm.iota.org), [ShimmerEVM Explorer](https://explorer.evm.testnet.shimmer.network/) or [EVM Testnet Explorer](https://explorer.evm.testnet.shimmer.network/) diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/allowance/allow.md b/docs/content/developer/iota-evm/how-tos/core-contracts/basics/allowance/allow.md similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/allowance/allow.md rename to docs/content/developer/iota-evm/how-tos/core-contracts/basics/allowance/allow.md diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/allowance/get-allowance.md b/docs/content/developer/iota-evm/how-tos/core-contracts/basics/allowance/get-allowance.md similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/allowance/get-allowance.md rename to docs/content/developer/iota-evm/how-tos/core-contracts/basics/allowance/get-allowance.md diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/allowance/take-allowance.md b/docs/content/developer/iota-evm/how-tos/core-contracts/basics/allowance/take-allowance.md similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/allowance/take-allowance.md rename to docs/content/developer/iota-evm/how-tos/core-contracts/basics/allowance/take-allowance.md diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/get-balance.md b/docs/content/developer/iota-evm/how-tos/core-contracts/basics/get-balance.md similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/get-balance.md rename to docs/content/developer/iota-evm/how-tos/core-contracts/basics/get-balance.md diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/send-assets-to-l1.mdx b/docs/content/developer/iota-evm/how-tos/core-contracts/basics/send-assets-to-l1.mdx similarity index 96% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/send-assets-to-l1.mdx rename to docs/content/developer/iota-evm/how-tos/core-contracts/basics/send-assets-to-l1.mdx index da6e36c0129..bf842e41a6d 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/basics/send-assets-to-l1.mdx +++ b/docs/content/developer/iota-evm/how-tos/core-contracts/basics/send-assets-to-l1.mdx @@ -10,7 +10,7 @@ tags: - Solidity --- -import AboutAccounts from '../../../../../../_snippets/iota-chains/about-accounts.md'; +import AboutAccounts from '../../../../../../_snippets/iota-evm/about-accounts.md'; # Send Assets and Tokens to L1 diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/call-view.md b/docs/content/developer/iota-evm/how-tos/core-contracts/call-view.md similarity index 67% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/call-view.md rename to docs/content/developer/iota-evm/how-tos/core-contracts/call-view.md index dbccbb974e4..716418cbbc4 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/call-view.md +++ b/docs/content/developer/iota-evm/how-tos/core-contracts/call-view.md @@ -14,7 +14,7 @@ tags: ## About `call` and `callView` -The magic contract provides you with a solidity interface to the core contracts. Some functions like [`getL2BalanceBaseTokens`](../../../../../references/iota-chains/magic-contract/ISCAccounts.md#getl2balancebasetokens) are wrapped in the magic contract directly, others you need to call yourself. You can do that with the [`call`](../../../../../references/iota-chains/magic-contract/ISCSandbox.md#call) and [`callView`](../../../../../references/iota-chains/magic-contract/ISCSandbox.md#callview) functions. +The magic contract provides you with a solidity interface to the core contracts. Some functions like [`getL2BalanceBaseTokens`](../../../../../references/iota-evm/magic-contract/ISCAccounts.md#getl2balancebasetokens) are wrapped in the magic contract directly, others you need to call yourself. You can do that with the [`call`](../../../../../references/iota-evm/magic-contract/ISCSandbox.md#call) and [`callView`](../../../../../references/iota-evm/magic-contract/ISCSandbox.md#callview) functions. :::info WASM @@ -30,7 +30,7 @@ You can also use `call` and `callView` to interact with WASM contracts. ISCAgentID memory agentID = ISC.sandbox.getSenderAccount(); ``` -2. Initialize the parameters for the call by creating a new [`ISCDict`](../../../../../references/iota-chains/magic-contract/ISCTypes.md#iscdict). As you can see in the docs, [`getl2balancenativetokens`](../../../../../references/iota-chains/magic-contract/ISCAccounts.md#getl2balancenativetokens) takes two parameters.: the Agent ID and the native token ID. So, you have to create a dictionary with two key-value pairs. The key of the first pair (Agent ID) has to be `a` and the key for the second pair (native token ID) `N`. +2. Initialize the parameters for the call by creating a new [`ISCDict`](../../../../../references/iota-evm/magic-contract/ISCTypes.md#iscdict). As you can see in the docs, [`getl2balancenativetokens`](../../../../../references/iota-evm/magic-contract/ISCAccounts.md#getl2balancenativetokens) takes two parameters.: the Agent ID and the native token ID. So, you have to create a dictionary with two key-value pairs. The key of the first pair (Agent ID) has to be `a` and the key for the second pair (native token ID) `N`. ```solidity ISCDict memory params = ISCDict(new ISCDictItem[](2)); @@ -38,7 +38,7 @@ params.items[0] = ISCDictItem("a", agentID.data); params.items[1] = ISCDictItem("N", nativeTokenID); ``` -3. Now, you can use [`callView`](../../../../../references/iota-chains/magic-contract/ISCSandbox.md#callview) to call our contract. The first parameter is the core contract `hname`, which we can get with the helper utility [`hn`](../../../../../references/iota-chains/magic-contract/ISCUtil.md#hn), and the second parameter is the function we want to call. The last parameter is the dictionary with all function parameters. +3. Now, you can use [`callView`](../../../../../references/iota-evm/magic-contract/ISCSandbox.md#callview) to call our contract. The first parameter is the core contract `hname`, which we can get with the helper utility [`hn`](../../../../../references/iota-evm/magic-contract/ISCUtil.md#hn), and the second parameter is the function we want to call. The last parameter is the dictionary with all function parameters. ```solidity ISCDict memory result = ISC.sandbox.callView( diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/get-randomness-on-l2.md b/docs/content/developer/iota-evm/how-tos/core-contracts/get-randomness-on-l2.md similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/get-randomness-on-l2.md rename to docs/content/developer/iota-evm/how-tos/core-contracts/get-randomness-on-l2.md diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/introduction.md b/docs/content/developer/iota-evm/how-tos/core-contracts/introduction.md similarity index 78% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/introduction.md rename to docs/content/developer/iota-evm/how-tos/core-contracts/introduction.md index 0c2fbfd6821..7efa57b33fc 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/introduction.md +++ b/docs/content/developer/iota-evm/how-tos/core-contracts/introduction.md @@ -15,14 +15,14 @@ tags: # The Core Contracts -The [core contracts](../../explanations/core-contracts.md) are contracts deployed on every chain and are vital to interact with L1 and the chain itself. They can be called in Solidity through the [ISC Magic Contract](../../../../../references/iota-chains/magic-contract/introduction.md). +The [core contracts](../../explanations/core-contracts.md) are contracts deployed on every chain and are vital to interact with L1 and the chain itself. They can be called in Solidity through the [ISC Magic Contract](../../../../../references/iota-evm/magic-contract/introduction.md). ## The ISC Magic Contract The Magic contract is an EVM contract deployed by default on every ISC chain, in the EVM genesis block, at address `0x1074000000000000000000000000000000000000`. The implementation of the Magic contract is baked-in in -the [`evm`](../../../../../references/iota-chains/core-contracts/evm.md) [core contract](../../../../../references/iota-chains/core-contracts/overview.md); +the [`evm`](../../../../../references/iota-evm/core-contracts/evm.md) [core contract](../../../../../references/iota-evm/core-contracts/overview.md); i.e. it is not a pure-Solidity contract. The Magic contract has several methods, which are categorized into specialized @@ -45,7 +45,7 @@ tokens and native tokens on L2. :::info Reference Docs -If you need further info about magic contracts interfaces you can check out the [magic contract docs](../../../../../references/iota-chains/magic-contract/introduction.md). +If you need further info about magic contracts interfaces you can check out the [magic contract docs](../../../../../references/iota-evm/magic-contract/introduction.md). ::: @@ -53,7 +53,7 @@ If you need further info about magic contracts interfaces you can check out the :::info Ease of use -To make it easier for developers to use the core contracts, you should, in most cases, run the functions from the magic contract directly. For example, to get the native token balance, you could [call the `balanceNativeToken()`](./call-view.md) directly with `callView`, or use [`getl2balancenativetokens`](./basics/get-balance.md) of the magic contract, or (the suggested way) register your native token as [`ERC20`](../../../../../references/iota-chains/magic-contract/ERC20NativeTokens.md) and call the standard [`balanceof`](../../../../../references/iota-chains/magic-contract/ERC20NativeTokens.md#balanceof) function. What you use also depends on what you optimize for. For example, to save gas, it could be interesting for you to call core contracts from your favorite web3 library directly and compute other things off-chain. +To make it easier for developers to use the core contracts, you should, in most cases, run the functions from the magic contract directly. For example, to get the native token balance, you could [call the `balanceNativeToken()`](./call-view.md) directly with `callView`, or use [`getl2balancenativetokens`](./basics/get-balance.md) of the magic contract, or (the suggested way) register your native token as [`ERC20`](../../../../../references/iota-evm/magic-contract/ERC20NativeTokens.md) and call the standard [`balanceof`](../../../../../references/iota-evm/magic-contract/ERC20NativeTokens.md#balanceof) function. What you use also depends on what you optimize for. For example, to save gas, it could be interesting for you to call core contracts from your favorite web3 library directly and compute other things off-chain. ::: diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/introduction.mdx b/docs/content/developer/iota-evm/how-tos/core-contracts/nft/introduction.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/introduction.mdx rename to docs/content/developer/iota-evm/how-tos/core-contracts/nft/introduction.mdx diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx b/docs/content/developer/iota-evm/how-tos/core-contracts/nft/mint-nft.mdx similarity index 89% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx rename to docs/content/developer/iota-evm/how-tos/core-contracts/nft/mint-nft.mdx index 83103c3accb..eeee6254b3f 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft.mdx +++ b/docs/content/developer/iota-evm/how-tos/core-contracts/nft/mint-nft.mdx @@ -6,7 +6,7 @@ tags: - EVM - how-to --- -import ExampleCodeIntro from '../../../../../../_snippets/iota-chains/how-tos/token/example_code_intro.mdx'; +import ExampleCodeIntro from '../../../../../../_snippets/iota-evm/how-tos/token/example_code_intro.mdx'; # Mint an NFT ## About NFTs @@ -35,7 +35,7 @@ IRC27NFTMetadata memory metadata = IRC27NFTMetadata({ }); ``` -4. Create all the data for the core contract call. To do so, you should create a new `ISCDict` with 2 parameters like specified in the reference docs for [`mintNFT`](../../../../../../references/iota-chains/core-contracts/accounts.md#mintnfti-immutabledata-a-agentid-c-collectionid-w-withdrawonmint) +4. Create all the data for the core contract call. To do so, you should create a new `ISCDict` with 2 parameters like specified in the reference docs for [`mintNFT`](../../../../../../references/iota-evm/core-contracts/accounts.md#mintnfti-immutabledata-a-agentid-c-collectionid-w-withdrawonmint) * `I` is the immutable metadata we fill with the IRC27 metadata and * `a` is the AgendID of the owner of the NFT @@ -51,7 +51,7 @@ The full example below calls the `IRC27NFTMetadataToString` function, which simp ::: -5. Call the magic contract `call` function with all the parameters. You should specify the core contract you want to call, which in this case is the [`account`](../../../../../../references/iota-chains/core-contracts/accounts.md) contract, and the function for [minting an NFT](../../../../../../references/iota-chains/core-contracts/accounts.md#mintnfti-immutabledata-a-agentid-c-collectionid-w-withdrawonmint) +5. Call the magic contract `call` function with all the parameters. You should specify the core contract you want to call, which in this case is the [`account`](../../../../../../references/iota-evm/core-contracts/accounts.md) contract, and the function for [minting an NFT](../../../../../../references/iota-evm/core-contracts/accounts.md#mintnfti-immutabledata-a-agentid-c-collectionid-w-withdrawonmint) ```solidity ISCDict memory ret = ISC.sandbox.call( @@ -62,7 +62,7 @@ ISCDict memory ret = ISC.sandbox.call( ); ``` -6. The call return value will contain a `mintID` which we can use in, for example, another contract function to get the actual L1 NFT ID once it is created using the [`accounts.NFTIDbyMintID`](../../../../../../references/iota-chains/core-contracts/accounts.md#nftidbymintidd-mintid) function +6. The call return value will contain a `mintID` which we can use in, for example, another contract function to get the actual L1 NFT ID once it is created using the [`accounts.NFTIDbyMintID`](../../../../../../references/iota-evm/core-contracts/accounts.md#nftidbymintidd-mintid) function ```solidity function getNFTIDFromMintID(bytes memory mintID) public view returns (bytes memory) { diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/use-as-erc721.md b/docs/content/developer/iota-evm/how-tos/core-contracts/nft/use-as-erc721.md similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/nft/use-as-erc721.md rename to docs/content/developer/iota-evm/how-tos/core-contracts/nft/use-as-erc721.md diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.mdx b/docs/content/developer/iota-evm/how-tos/core-contracts/token/create-foundry.mdx similarity index 92% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.mdx rename to docs/content/developer/iota-evm/how-tos/core-contracts/token/create-foundry.mdx index b94cb04e099..3893ff63d57 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry.mdx +++ b/docs/content/developer/iota-evm/how-tos/core-contracts/token/create-foundry.mdx @@ -6,8 +6,8 @@ tags: - EVM - how-to --- -import ExampleCodeIntro from '../../../../../../_snippets/iota-chains/how-tos/token/example_code_intro.mdx'; -import ObsoleteTokenCreation from '../../../../../../_snippets/iota-chains/how-tos/token/obsolete_token_creation.md'; +import ExampleCodeIntro from '../../../../../../_snippets/iota-evm/how-tos/token/example_code_intro.mdx'; +import ObsoleteTokenCreation from '../../../../../../_snippets/iota-evm/how-tos/token/obsolete_token_creation.md'; # Create a Foundry diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx b/docs/content/developer/iota-evm/how-tos/core-contracts/token/create-native-token.mdx similarity index 79% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx rename to docs/content/developer/iota-evm/how-tos/core-contracts/token/create-native-token.mdx index 4c97022dd16..d8c30e9a017 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token.mdx +++ b/docs/content/developer/iota-evm/how-tos/core-contracts/token/create-native-token.mdx @@ -10,11 +10,11 @@ tags: - register --- -import ExampleCodeIntro from '../../../../../../_snippets/iota-chains/how-tos/token/example_code_intro.mdx'; +import ExampleCodeIntro from '../../../../../../_snippets/iota-evm/how-tos/token/example_code_intro.mdx'; # Create a Native Token -This guide will show you how you can efficiently mint new tokens and register them for use as ERC20 tokens with the [`createNativeTokenFoundry`](../../../../../../references/iota-chains/magic-contract/ISCAccounts.md#createnativetokenfoundry) function in one seamless operation. It will create a foundry on L1 and register it as an ERC20 on L2. This method ensures that only the foundry owner can mint tokens, maintaining security and control over the token creation process. +This guide will show you how you can efficiently mint new tokens and register them for use as ERC20 tokens with the [`createNativeTokenFoundry`](../../../../../../references/iota-evm/magic-contract/ISCAccounts.md#createnativetokenfoundry) function in one seamless operation. It will create a foundry on L1 and register it as an ERC20 on L2. This method ensures that only the foundry owner can mint tokens, maintaining security and control over the token creation process. ## About Foundries @@ -27,7 +27,7 @@ The Foundry lets you specify your native token's maximum supply **once** and cha ### 2. Define the Token Scheme -Define the [`NativeTokenScheme`](../../../../../../references/iota-chains/magic-contract/ISCTypes.md#nativetokenscheme) by specifying the `maximumSupply`. +Define the [`NativeTokenScheme`](../../../../../../references/iota-evm/magic-contract/ISCTypes.md#nativetokenscheme) by specifying the `maximumSupply`. ```solidity NativeTokenScheme memory nativeTokenScheme = NativeTokenScheme({ @@ -39,7 +39,7 @@ NativeTokenScheme memory nativeTokenScheme = NativeTokenScheme({ ### 3. Mint and Register Native Token -Minting native tokens and registering them as ERC20 tokens using [`createNativeTokenFoundry`](../../../../../../references/iota-chains/magic-contract/ISCAccounts.md#createnativetokenfoundry) method +Minting native tokens and registering them as ERC20 tokens using [`createNativeTokenFoundry`](../../../../../../references/iota-evm/magic-contract/ISCAccounts.md#createnativetokenfoundry) method ```solidity uint32 foundrySN = ISC.accounts.createNativeTokenFoundry( diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/erc20-native-token.md b/docs/content/developer/iota-evm/how-tos/core-contracts/token/erc20-native-token.md similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/erc20-native-token.md rename to docs/content/developer/iota-evm/how-tos/core-contracts/token/erc20-native-token.md diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/introduction.mdx b/docs/content/developer/iota-evm/how-tos/core-contracts/token/introduction.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/introduction.mdx rename to docs/content/developer/iota-evm/how-tos/core-contracts/token/introduction.mdx diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.mdx b/docs/content/developer/iota-evm/how-tos/core-contracts/token/mint-token.mdx similarity index 92% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.mdx rename to docs/content/developer/iota-evm/how-tos/core-contracts/token/mint-token.mdx index f643c908c1c..6d6a5f239c7 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/mint-token.mdx +++ b/docs/content/developer/iota-evm/how-tos/core-contracts/token/mint-token.mdx @@ -8,7 +8,7 @@ tags: - native tokens - mint --- -import ExampleCodeIntro from '../../../../../../_snippets/iota-chains/how-tos/token/example_code_intro.mdx'; +import ExampleCodeIntro from '../../../../../../_snippets/iota-evm/how-tos/token/example_code_intro.mdx'; # Mint Native Tokens diff --git a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/register-token.mdx b/docs/content/developer/iota-evm/how-tos/core-contracts/token/register-token.mdx similarity index 90% rename from docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/register-token.mdx rename to docs/content/developer/iota-evm/how-tos/core-contracts/token/register-token.mdx index 9b004ab9290..557e6c451b9 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/core-contracts/token/register-token.mdx +++ b/docs/content/developer/iota-evm/how-tos/core-contracts/token/register-token.mdx @@ -6,8 +6,8 @@ tags: - EVM - how-to --- -import ExampleCodeIntro from '../../../../../../_snippets/iota-chains/how-tos/token/example_code_intro.mdx'; -import ObsoleteTokenCreation from '../../../../../../_snippets/iota-chains/how-tos/token/obsolete_token_creation.md'; +import ExampleCodeIntro from '../../../../../../_snippets/iota-evm/how-tos/token/example_code_intro.mdx'; +import ObsoleteTokenCreation from '../../../../../../_snippets/iota-evm/how-tos/token/obsolete_token_creation.md'; # Register Tokens diff --git a/docs/content/guides/developer/iota-chains/how-tos/create-a-basic-contract.mdx b/docs/content/developer/iota-evm/how-tos/create-a-basic-contract.mdx similarity index 93% rename from docs/content/guides/developer/iota-chains/how-tos/create-a-basic-contract.mdx rename to docs/content/developer/iota-evm/how-tos/create-a-basic-contract.mdx index 5ec87ab79f2..3056080fe4a 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/create-a-basic-contract.mdx +++ b/docs/content/developer/iota-evm/how-tos/create-a-basic-contract.mdx @@ -6,7 +6,7 @@ tags: - how to - basic contract --- -import DeployAdmonition from '../../../../_snippets/iota-chains/deploy_a_smart_contract.md'; +import DeployAdmonition from '../../../../_snippets/iota-evm/deploy_a_smart_contract.md'; # Basic Smart Contract Example diff --git a/docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx b/docs/content/developer/iota-evm/how-tos/deploy-a-smart-contract.mdx similarity index 96% rename from docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx rename to docs/content/developer/iota-evm/how-tos/deploy-a-smart-contract.mdx index d18e70ce583..9fdda126788 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/deploy-a-smart-contract.mdx +++ b/docs/content/developer/iota-evm/how-tos/deploy-a-smart-contract.mdx @@ -10,8 +10,8 @@ image: /img/logo/WASP_logo_dark.png description: 'Learn how to deploy smart contracts to IOTA EVM, Shimmer EVM and EVM Testnet using popular tools like Remix and Hardhat.' --- import {AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; -import HardhatConfig from '../../../../_snippets/iota-chains/hardhat_config.mdx'; -import MetamaskButtons from '../../../../_snippets/iota-chains/metamask_buttons.mdx'; +import HardhatConfig from '../../../../_snippets/iota-evm/hardhat_config.mdx'; +import MetamaskButtons from '../../../../_snippets/iota-evm/metamask_buttons.mdx'; import { Networks } from '@theme/constant'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; @@ -70,7 +70,7 @@ Open your web browser and navigate to [Remix IDE](https://remix.ethereum.org/). 1. Switch to the "Deploy & Run Transactions" tab on the left sidebar. 2. In the "Environment" dropdown, select and select `Injected Web3` from the `Environment` dropdown. - ![Select Injected Provider from the Environment dropdown](/img/iota-chains/evm/remix-injected-provider-metamask.png) + ![Select Injected Provider from the Environment dropdown](/img/iota-evm/evm/remix-injected-provider-metamask.png) 3. After selecting the environment, make sure the contract Counter is selected in the `Contract` dropdown. 4. Click the `Deploy` button. If you're using an Ethereum network, confirm the transaction in your Web3 wallet. diff --git a/docs/content/guides/developer/iota-chains/how-tos/introduction.md b/docs/content/developer/iota-evm/how-tos/introduction.md similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/introduction.md rename to docs/content/developer/iota-evm/how-tos/introduction.md diff --git a/docs/content/guides/developer/iota-chains/how-tos/send-ERC20-across-chains.md b/docs/content/developer/iota-evm/how-tos/send-ERC20-across-chains.md similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/send-ERC20-across-chains.md rename to docs/content/developer/iota-evm/how-tos/send-ERC20-across-chains.md diff --git a/docs/content/guides/developer/iota-chains/how-tos/send-NFTs-across-chains.md b/docs/content/developer/iota-evm/how-tos/send-NFTs-across-chains.md similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/send-NFTs-across-chains.md rename to docs/content/developer/iota-evm/how-tos/send-NFTs-across-chains.md diff --git a/docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx b/docs/content/developer/iota-evm/how-tos/send-funds-from-L1-to-L2.mdx similarity index 72% rename from docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx rename to docs/content/developer/iota-evm/how-tos/send-funds-from-L1-to-L2.mdx index 48808d45ce7..44222d8c130 100644 --- a/docs/content/guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2.mdx +++ b/docs/content/developer/iota-evm/how-tos/send-funds-from-L1-to-L2.mdx @@ -17,7 +17,7 @@ tags: import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import {AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; -import MetamaskButtons from '../../../../_snippets/iota-chains/metamask_buttons.mdx'; +import MetamaskButtons from '../../../../_snippets/iota-evm/metamask_buttons.mdx'; import { Networks } from '@theme/constant'; # Send Funds From L1 to L2 @@ -53,23 +53,23 @@ You can use your [Firefly Wallet](https://firefly.iota.org/) to easily send L1 I 2. Once you have added the EVM to Metamask, you can get your address: - ![Copy your Metamask address](/img/iota-chains/evm/how-tos/get-funds/copy-your-address.png) + ![Copy your Metamask address](/img/iota-evm/evm/how-tos/get-funds/copy-your-address.png) 3. Next, you will need to open your [Firefly Wallet](https://firefly.iota.org/) and click on `Send Assets`. - ![Click send assets](/img/iota-chains/evm/how-tos/get-funds/firefly/select-send-assets.png) + ![Click send assets](/img/iota-evm/evm/how-tos/get-funds/firefly/select-send-assets.png) 4. Select the EVM chain you want to use in the network dropdown. - ![Select the EVM network](/img/iota-chains/evm/how-tos/get-funds/firefly/select-shimmer-evm.png) + ![Select the EVM network](/img/iota-evm/evm/how-tos/get-funds/firefly/select-shimmer-evm.png) 5. Enter the amount of tokens you want to transfer, and the Metamask address from step 2, and click on `Next` - ![Enter the amount of tokens and metamask address](/img/iota-chains/evm/how-tos/get-funds/firefly/enter-your-desired-amount-and-metamask-address.png) + ![Enter the amount of tokens and metamask address](/img/iota-evm/evm/how-tos/get-funds/firefly/enter-your-desired-amount-and-metamask-address.png) 6. Review the transaction details and click on `Send`. - ![Hit Send](/img/iota-chains/evm/how-tos/get-funds/firefly/hit-send.png) + ![Hit Send](/img/iota-evm/evm/how-tos/get-funds/firefly/hit-send.png) @@ -79,24 +79,24 @@ You can use your [Bloom Wallet](https://bloomwallet.io/) to easily send L1 base 1. First, you will need to open your [Bloom Wallet](https://firefly.iota.org/) and click on `Send`. - ![Click send](/img/iota-chains/evm/how-tos/get-funds/bloom/select-send.png) + ![Click send](/img/iota-evm/evm/how-tos/get-funds/bloom/select-send.png) 2. Select an account with base tokens. - ![Select an account with base tokens](/img/iota-chains/evm/how-tos/get-funds/bloom/select-the-smr-token.png) + ![Select an account with base tokens](/img/iota-evm/evm/how-tos/get-funds/bloom/select-the-smr-token.png) 3. Bloom will automatically create an EVM address for you, so you can send funds to that address from the EVM dropdown. Alternatively, you can input any other EVM address. - ![Select you EVM Address](/img/iota-chains/evm/how-tos/get-funds/bloom/enter-the-recipient-address.png) + ![Select you EVM Address](/img/iota-evm/evm/how-tos/get-funds/bloom/enter-the-recipient-address.png) 4. Enter the amount of base tokens you want to transfer. - ![Enter the amount of base tokens you want to transfer](/img/iota-chains/evm/how-tos/get-funds/bloom/enter-the-amount.png) + ![Enter the amount of base tokens you want to transfer](/img/iota-evm/evm/how-tos/get-funds/bloom/enter-the-amount.png) 5. Review the transaction details and click on `Confirm`. - ![Hit Send](/img/iota-chains/evm/how-tos/get-funds/bloom/review-and-confirm-the-transaction.png) + ![Hit Send](/img/iota-evm/evm/how-tos/get-funds/bloom/review-and-confirm-the-transaction.png) \ No newline at end of file diff --git a/docs/content/guides/developer/iota-chains/how-tos/test-smart-contracts.md b/docs/content/developer/iota-evm/how-tos/test-smart-contracts.md similarity index 100% rename from docs/content/guides/developer/iota-chains/how-tos/test-smart-contracts.md rename to docs/content/developer/iota-evm/how-tos/test-smart-contracts.md diff --git a/docs/content/guides/developer/iota-chains/introduction.mdx b/docs/content/developer/iota-evm/introduction.mdx similarity index 93% rename from docs/content/guides/developer/iota-chains/introduction.mdx rename to docs/content/developer/iota-evm/introduction.mdx index e54cf1ddfc8..02b79068165 100644 --- a/docs/content/guides/developer/iota-chains/introduction.mdx +++ b/docs/content/developer/iota-evm/introduction.mdx @@ -11,7 +11,7 @@ tags: - explanation --- -import OnOffLedgerRequest from '../../../_snippets/iota-chains/on_off_ledger_request.md'; +import OnOffLedgerRequest from '../../../_snippets/iota-evm/on_off_ledger_request.md'; # Introduction @@ -37,7 +37,7 @@ As validator nodes execute the smart contracts, they tally these state changes a In turn ISC chains, each with their state and smart contracts, update their state collectively and interact with Layer 1 and other L2 chains, offering a sophisticated multi-chain architecture. -![IOTA Smart Contacts multichain architecture](/img/iota-chains/multichain.png 'Click to see the full-size image.') +![IOTA Smart Contacts multichain architecture](/img/iota-evm/multichain.png 'Click to see the full-size image.') _IOTA Smart Contacts multichain architecture._ @@ -55,7 +55,7 @@ ISC Smart contracts can access the [Sandbox interface](explanations/sandbox.md). This interface provides access to the chain state, native assets, allows interaction with other contracts/chains, as well as various utilities like cryptographic functions and event dispatching. -![Sandbox](/img/iota-chains/sandbox.png) +![Sandbox](/img/iota-evm/sandbox.png) ## Calling a Smart Contract diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/access.mdx b/docs/content/developer/iota-evm/schema/how-tos/access.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/schema/how-tos/access.mdx rename to docs/content/developer/iota-evm/schema/how-tos/access.mdx diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/call.mdx b/docs/content/developer/iota-evm/schema/how-tos/call.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/schema/how-tos/call.mdx rename to docs/content/developer/iota-evm/schema/how-tos/call.mdx diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/events.mdx b/docs/content/developer/iota-evm/schema/how-tos/events.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/schema/how-tos/events.mdx rename to docs/content/developer/iota-evm/schema/how-tos/events.mdx diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/funcdesc.mdx b/docs/content/developer/iota-evm/schema/how-tos/funcdesc.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/schema/how-tos/funcdesc.mdx rename to docs/content/developer/iota-evm/schema/how-tos/funcdesc.mdx diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/funcs.mdx b/docs/content/developer/iota-evm/schema/how-tos/funcs.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/schema/how-tos/funcs.mdx rename to docs/content/developer/iota-evm/schema/how-tos/funcs.mdx diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/init.mdx b/docs/content/developer/iota-evm/schema/how-tos/init.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/schema/how-tos/init.mdx rename to docs/content/developer/iota-evm/schema/how-tos/init.mdx diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/params.mdx b/docs/content/developer/iota-evm/schema/how-tos/params.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/schema/how-tos/params.mdx rename to docs/content/developer/iota-evm/schema/how-tos/params.mdx diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/post.mdx b/docs/content/developer/iota-evm/schema/how-tos/post.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/schema/how-tos/post.mdx rename to docs/content/developer/iota-evm/schema/how-tos/post.mdx diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/results.mdx b/docs/content/developer/iota-evm/schema/how-tos/results.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/schema/how-tos/results.mdx rename to docs/content/developer/iota-evm/schema/how-tos/results.mdx diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/spec.mdx b/docs/content/developer/iota-evm/schema/how-tos/spec.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/schema/how-tos/spec.mdx rename to docs/content/developer/iota-evm/schema/how-tos/spec.mdx diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/state.mdx b/docs/content/developer/iota-evm/schema/how-tos/state.mdx similarity index 99% rename from docs/content/guides/developer/iota-chains/schema/how-tos/state.mdx rename to docs/content/developer/iota-evm/schema/how-tos/state.mdx index 9bbae269b95..e70bb5de702 100644 --- a/docs/content/guides/developer/iota-chains/schema/how-tos/state.mdx +++ b/docs/content/developer/iota-evm/schema/how-tos/state.mdx @@ -55,7 +55,7 @@ state: Starting with straightforward state variables, `totalFactor`, and `owner` are characterized as Uint64 and AgentID, respectively. -These represent predefined [WasmLib value types](../../../../../references/iota-chains/wasm-lib-data-types.mdx). +These represent predefined [WasmLib value types](../../../../../references/iota-evm/wasm-lib-data-types.mdx). ### Arrays and Maps diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/structs.mdx b/docs/content/developer/iota-evm/schema/how-tos/structs.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/schema/how-tos/structs.mdx rename to docs/content/developer/iota-evm/schema/how-tos/structs.mdx diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/thunks.mdx b/docs/content/developer/iota-evm/schema/how-tos/thunks.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/schema/how-tos/thunks.mdx rename to docs/content/developer/iota-evm/schema/how-tos/thunks.mdx diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/transfers.mdx b/docs/content/developer/iota-evm/schema/how-tos/transfers.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/schema/how-tos/transfers.mdx rename to docs/content/developer/iota-evm/schema/how-tos/transfers.mdx diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/typedefs.mdx b/docs/content/developer/iota-evm/schema/how-tos/typedefs.mdx similarity index 99% rename from docs/content/guides/developer/iota-chains/schema/how-tos/typedefs.mdx rename to docs/content/developer/iota-evm/schema/how-tos/typedefs.mdx index d56b98a2adb..0447b2b4f7b 100644 --- a/docs/content/guides/developer/iota-chains/schema/how-tos/typedefs.mdx +++ b/docs/content/developer/iota-evm/schema/how-tos/typedefs.mdx @@ -19,7 +19,7 @@ import TabItem from '@theme/TabItem'; :::note WasmLib Types -You can find the complete list of [WasmLib Data Types](../../../../../references/iota-chains/wasm-lib-data-types.mdx) in the reference section. +You can find the complete list of [WasmLib Data Types](../../../../../references/iota-evm/wasm-lib-data-types.mdx) in the reference section. ::: diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/usage.mdx b/docs/content/developer/iota-evm/schema/how-tos/usage.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/schema/how-tos/usage.mdx rename to docs/content/developer/iota-evm/schema/how-tos/usage.mdx diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/views.mdx b/docs/content/developer/iota-evm/schema/how-tos/views.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/schema/how-tos/views.mdx rename to docs/content/developer/iota-evm/schema/how-tos/views.mdx diff --git a/docs/content/guides/developer/iota-chains/schema/how-tos/yaml.mdx b/docs/content/developer/iota-evm/schema/how-tos/yaml.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/schema/how-tos/yaml.mdx rename to docs/content/developer/iota-evm/schema/how-tos/yaml.mdx diff --git a/docs/content/guides/developer/iota-chains/schema/introduction.mdx b/docs/content/developer/iota-evm/schema/introduction.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/schema/introduction.mdx rename to docs/content/developer/iota-evm/schema/introduction.mdx diff --git a/docs/content/guides/developer/iota-chains/schema/proxies.mdx b/docs/content/developer/iota-evm/schema/proxies.mdx similarity index 97% rename from docs/content/guides/developer/iota-chains/schema/proxies.mdx rename to docs/content/developer/iota-evm/schema/proxies.mdx index 2b2a0f5c7ec..1b5bbb07803 100644 --- a/docs/content/guides/developer/iota-chains/schema/proxies.mdx +++ b/docs/content/developer/iota-evm/schema/proxies.mdx @@ -9,7 +9,7 @@ tags: - map proxies - explanation description: As there is no way for the Wasm code to access any memory outside its own memory space, the WasmLib interface provides a number of proxies to make accessing data within the ISC sandbox as seamless as possible. -image: /img/iota-chains/wasm_vm/Proxies.png +image: /img/iota-evm/wasm_vm/Proxies.png --- # Data Access Proxies @@ -67,7 +67,7 @@ They use JSON and YAML nesting patterns, and there are two primary types: ## Proxies in Action -![Proxies in WasmLib](/img/iota-chains/wasm_vm/Proxies.png) +![Proxies in WasmLib](/img/iota-evm/wasm_vm/Proxies.png) In the illustration, we see the key-value combinations (Key 1 to Key 4) in the ISC state storage map. Key 4 directs us to an array containing indexed values ranging from 0 to N. diff --git a/docs/content/guides/developer/iota-chains/solo/getting-started.md b/docs/content/developer/iota-evm/solo/getting-started.md similarity index 100% rename from docs/content/guides/developer/iota-chains/solo/getting-started.md rename to docs/content/developer/iota-evm/solo/getting-started.md diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/deploying-sc.md b/docs/content/developer/iota-evm/solo/how-tos/deploying-sc.md similarity index 97% rename from docs/content/guides/developer/iota-chains/solo/how-tos/deploying-sc.md rename to docs/content/developer/iota-evm/solo/how-tos/deploying-sc.md index 8d971d60690..aa3a6ec9cd6 100644 --- a/docs/content/guides/developer/iota-chains/solo/how-tos/deploying-sc.md +++ b/docs/content/developer/iota-evm/solo/how-tos/deploying-sc.md @@ -1,6 +1,6 @@ --- description: Deploying Wasm smart contracts with Solo. -image: /img/iota-chains/tutorial/send_request.png +image: /img/iota-evm/tutorial/send_request.png tags: - testing - PostRequestSync diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/error-handling.md b/docs/content/developer/iota-evm/solo/how-tos/error-handling.md similarity index 96% rename from docs/content/guides/developer/iota-chains/solo/how-tos/error-handling.md rename to docs/content/developer/iota-evm/solo/how-tos/error-handling.md index a22ac10f734..66605e4bbd4 100644 --- a/docs/content/guides/developer/iota-chains/solo/how-tos/error-handling.md +++ b/docs/content/developer/iota-evm/solo/how-tos/error-handling.md @@ -44,7 +44,7 @@ Note that this test still ends with the state `#4`, although the last request to ``` This shows that a chain block is always generated, regardless of whether the smart contract call succeeds or not. The -result of the request is stored in the chain's [`blocklog`](../../../../../references/iota-chains/core-contracts/blocklog.md) in the form of +result of the request is stored in the chain's [`blocklog`](../../../../../references/iota-evm/core-contracts/blocklog.md) in the form of a receipt. In fact, the received Go error `err` in the test above is just generated from the request receipt. If a panic occurs during a smart contract call, it is recovered by the VM context, and the request is marked as failed. diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/examples.mdx b/docs/content/developer/iota-evm/solo/how-tos/examples.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/solo/how-tos/examples.mdx rename to docs/content/developer/iota-evm/solo/how-tos/examples.mdx diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/first-example.md b/docs/content/developer/iota-evm/solo/how-tos/first-example.md similarity index 93% rename from docs/content/guides/developer/iota-chains/solo/how-tos/first-example.md rename to docs/content/developer/iota-evm/solo/how-tos/first-example.md index c4ba435ebe9..e9a93893f4a 100644 --- a/docs/content/guides/developer/iota-chains/solo/how-tos/first-example.md +++ b/docs/content/developer/iota-evm/solo/how-tos/first-example.md @@ -13,8 +13,8 @@ tags: # First Example The following is an example of a _Solo_ test. It deploys a new chain and invokes some view calls in the -[`root`](../../../../../references/iota-chains/core-contracts/root.md) and [`governance`](../../../../../references/iota-chains/core-contracts/governance.md) -[core contracts](../../../../../references/iota-chains/core-contracts/overview.md). +[`root`](../../../../../references/iota-evm/core-contracts/root.md) and [`governance`](../../../../../references/iota-evm/core-contracts/governance.md) +[core contracts](../../../../../references/iota-evm/core-contracts/overview.md). ```go import ( @@ -81,7 +81,7 @@ The output of the test will be something like this: ::: -The [core contracts](../../../../../references/iota-chains/core-contracts/overview.md) listed in the log are automatically deployed on each +The [core contracts](../../../../../references/iota-evm/core-contracts/overview.md) listed in the log are automatically deployed on each new chain. The log also shows their _contract IDs_. The output fragment in the log `state transition --> #1` means that the state of the chain has changed from block index diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/invoking-sc.md b/docs/content/developer/iota-evm/solo/how-tos/invoking-sc.md similarity index 97% rename from docs/content/guides/developer/iota-chains/solo/how-tos/invoking-sc.md rename to docs/content/developer/iota-evm/solo/how-tos/invoking-sc.md index 5a502cac050..2ff6fd68f1d 100644 --- a/docs/content/guides/developer/iota-chains/solo/how-tos/invoking-sc.md +++ b/docs/content/developer/iota-evm/solo/how-tos/invoking-sc.md @@ -1,6 +1,6 @@ --- description: Invoking smart contracts with on-ledger and off-ledger requests with Solo. -image: /img/iota-chains/tutorial/send_request.png +image: /img/iota-evm/tutorial/send_request.png tags: - how-to - explanation @@ -62,7 +62,7 @@ not necessary to manually deposit more funds for gas. ## On-Ledger Requests -[![Generic process of posting an on-ledger request to the smart contract](/img/iota-chains/tutorial/send_request.png)](/img/iota-chains/tutorial/send_request.png) +[![Generic process of posting an on-ledger request to the smart contract](/img/iota-evm/tutorial/send_request.png)](/img/iota-evm/tutorial/send_request.png) The diagram above depicts the generic process of posting an _on-ledger_ request to the smart contract. The same diagram is valid for the Solo environment and any other requester that sends an on-ledger request, e.g., the diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/test.mdx b/docs/content/developer/iota-evm/solo/how-tos/test.mdx similarity index 97% rename from docs/content/guides/developer/iota-chains/solo/how-tos/test.mdx rename to docs/content/developer/iota-evm/solo/how-tos/test.mdx index f6d0cd5b4b5..07b4b752387 100644 --- a/docs/content/guides/developer/iota-chains/solo/how-tos/test.mdx +++ b/docs/content/developer/iota-evm/solo/how-tos/test.mdx @@ -26,7 +26,7 @@ combination with Solo to deploy chains and smart contracts and simulate transact Solo directly interacts with the ISC code, and therefore uses all the ISC-specific data types directly. Our Wasm smart contracts cannot access these types directly, because they run in a separate, sandboxed environment. Therefore, WasmLib implements its -[own versions](../../../../../references/iota-chains/wasm-lib-data-types.mdx) of these data types, and the _VM_ layer acts as a data type +[own versions](../../../../../references/iota-evm/wasm-lib-data-types.mdx) of these data types, and the _VM_ layer acts as a data type translator between both systems. The impact of this type transformation used to be that to be able to write tests in the diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/the-l1-ledger.md b/docs/content/developer/iota-evm/solo/how-tos/the-l1-ledger.md similarity index 100% rename from docs/content/guides/developer/iota-chains/solo/how-tos/the-l1-ledger.md rename to docs/content/developer/iota-evm/solo/how-tos/the-l1-ledger.md diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/the-l2-ledger.md b/docs/content/developer/iota-evm/solo/how-tos/the-l2-ledger.md similarity index 96% rename from docs/content/guides/developer/iota-chains/solo/how-tos/the-l2-ledger.md rename to docs/content/developer/iota-evm/solo/how-tos/the-l2-ledger.md index 58dd8b2c0b4..02f2af5823f 100644 --- a/docs/content/guides/developer/iota-chains/solo/how-tos/the-l2-ledger.md +++ b/docs/content/developer/iota-evm/solo/how-tos/the-l2-ledger.md @@ -100,10 +100,10 @@ func TestTutorialAccounts(t *testing.T) { The example above creates a chain and a wallet with `utxodb.FundsFromFaucetAmount` base tokens on L1. Then, it sends 1 million tokens to the corresponding on-chain account by posting a -[`deposit`](../../../../../references/iota-chains/core-contracts/accounts.md#deposit) request to the -[`accounts` core contract](../../../../../references/iota-chains/core-contracts/accounts.md) on the chain. +[`deposit`](../../../../../references/iota-evm/core-contracts/accounts.md#deposit) request to the +[`accounts` core contract](../../../../../references/iota-evm/core-contracts/accounts.md) on the chain. -Finally, it sends a [`withdraw`](../../../../../references/iota-chains/core-contracts/accounts.md#withdraw) request to the `accounts` core +Finally, it sends a [`withdraw`](../../../../../references/iota-evm/core-contracts/accounts.md#withdraw) request to the `accounts` core contract to get the tokens back to L1. Both requests are affected by the gas fees and the storage deposit. diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/timelock.mdx b/docs/content/developer/iota-evm/solo/how-tos/timelock.mdx similarity index 100% rename from docs/content/guides/developer/iota-chains/solo/how-tos/timelock.mdx rename to docs/content/developer/iota-evm/solo/how-tos/timelock.mdx diff --git a/docs/content/guides/developer/iota-chains/solo/how-tos/view-sc.md b/docs/content/developer/iota-evm/solo/how-tos/view-sc.md similarity index 90% rename from docs/content/guides/developer/iota-chains/solo/how-tos/view-sc.md rename to docs/content/developer/iota-evm/solo/how-tos/view-sc.md index dfe8ab10a9b..d616ee717c8 100644 --- a/docs/content/guides/developer/iota-chains/solo/how-tos/view-sc.md +++ b/docs/content/developer/iota-evm/solo/how-tos/view-sc.md @@ -1,6 +1,6 @@ --- description: Calling smart contract view functions with Solo. -image: /img/iota-chains/tutorial/call_view.png +image: /img/iota-evm/tutorial/call_view.png tags: - how to - testing @@ -22,7 +22,7 @@ res, err := chain.CallView("example1", "getString") The call returns a collection of key/value pairs `res` and an error result `err` in the typical Go fashion. -[![Calling a view process](/img/iota-chains/tutorial/call_view.png)](/img/iota-chains/tutorial/call_view.png) +[![Calling a view process](/img/iota-evm/tutorial/call_view.png)](/img/iota-evm/tutorial/call_view.png) The basic principle of calling a view is similar to sending a request to the smart contract. The essential difference is that calling a view does not constitute an asynchronous transaction; it is just a direct synchronous call to the view @@ -33,7 +33,7 @@ view entry point will result in an exception, returning all attached tokens to t Views are used to retrieve information about the smart contract's state, for example, to display on a website. Certain Solo methods such as `chain.GetInfo`, `chain.GetGasFeePolicy`, and `chain.L2Assets` call views of -the [core smart contracts](../../../../../references/iota-chains/core-contracts/overview.md) behind the scenes to retrieve the information +the [core smart contracts](../../../../../references/iota-evm/core-contracts/overview.md) behind the scenes to retrieve the information about the chain or a specific smart contract. ## Decoding Results Returned by _PostRequestSync_ and _CallView_ diff --git a/docs/content/guides/developer/iota-chains/explanations/core-contracts.md b/docs/content/guides/developer/iota-chains/explanations/core-contracts.md deleted file mode 100644 index bdade2dfdd7..00000000000 --- a/docs/content/guides/developer/iota-chains/explanations/core-contracts.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -description: There currently are 6 core smart contracts that are always deployed on each chain, root, _default, accounts, blob, blocklog, and governance. -image: /img/banner/banner_wasp_core_contracts_overview.png -tags: - - smart contracts - - core - - initialization - - request handling - - on-chain ledger - - accounts - - data - - receipts - - reference ---- - -# Core Contracts - -![Wasp Node Core Contracts Overview](/img/banner/banner_wasp_core_contracts_overview.png) - -There are currently 7 core smart contracts that are always deployed on each -chain. These are responsible for the vital functions of the chain and -provide infrastructure for all other smart contracts: - -- [`root`](../../../../references/iota-chains/core-contracts/root.md): Responsible for the initialization of the chain, maintains registry of deployed contracts. - -- [`accounts`](../../../../references/iota-chains/core-contracts/accounts.md): Manages the on-chain ledger of accounts. - -- [`blob`](../../../../references/iota-chains/core-contracts/blob.md): Responsible for the registry of binary objects of arbitrary size. - -- [`blocklog`](../../../../references/iota-chains/core-contracts/blocklog.md): Keeps track of the blocks and receipts of requests that were processed by the chain. - -- [`governance`](../../../../references/iota-chains/core-contracts/governance.md): Handles the administrative functions of the chain. For example: rotation of the committee of validators of the chain, fees and other chain-specific configurations. - -- [`errors`](../../../../references/iota-chains/core-contracts/errors.md): Keeps a map of error codes to error messages templates. These error codes are used in request receipts. - -- [`evm`](../../../../references/iota-chains/core-contracts/evm.md): Provides the necessary infrastructure to accept Ethereum - transactions and execute EVM code. diff --git a/docs/content/guides/operator/iota-chains-node/how-tos/chain-management.md b/docs/content/operator/iota-evm/how-tos/chain-management.md similarity index 96% rename from docs/content/guides/operator/iota-chains-node/how-tos/chain-management.md rename to docs/content/operator/iota-evm/how-tos/chain-management.md index 6feb4d92f5c..4d9fa4a1f91 100644 --- a/docs/content/guides/operator/iota-chains-node/how-tos/chain-management.md +++ b/docs/content/operator/iota-evm/how-tos/chain-management.md @@ -20,7 +20,7 @@ You can view the chain state using the dashboard (`/wasp/dashboard` when us ## Manage Chain Configuration and Validators You can manage the chain configuration and committee of validators by interacting with -the [Governance contract](/isc/../../../references/iota-chains/core-contracts/governance). +the [Governance contract](/isc/../../../references/iota-evm/core-contracts/governance). The “Chain Owner” is the only one who can perform administrative tasks. diff --git a/docs/content/guides/operator/iota-chains-node/how-tos/running-a-node.md b/docs/content/operator/iota-evm/how-tos/running-a-node.md similarity index 100% rename from docs/content/guides/operator/iota-chains-node/how-tos/running-a-node.md rename to docs/content/operator/iota-evm/how-tos/running-a-node.md diff --git a/docs/content/guides/operator/iota-chains-node/how-tos/running-an-access-node.mdx b/docs/content/operator/iota-evm/how-tos/running-an-access-node.mdx similarity index 100% rename from docs/content/guides/operator/iota-chains-node/how-tos/running-an-access-node.mdx rename to docs/content/operator/iota-evm/how-tos/running-an-access-node.mdx diff --git a/docs/content/guides/operator/iota-chains-node/how-tos/setting-up-a-chain.md b/docs/content/operator/iota-evm/how-tos/setting-up-a-chain.md similarity index 96% rename from docs/content/guides/operator/iota-chains-node/how-tos/setting-up-a-chain.md rename to docs/content/operator/iota-evm/how-tos/setting-up-a-chain.md index ab8a5f90337..0ad532a1b30 100644 --- a/docs/content/guides/operator/iota-chains-node/how-tos/setting-up-a-chain.md +++ b/docs/content/operator/iota-evm/how-tos/setting-up-a-chain.md @@ -84,7 +84,7 @@ From now on, all chain commands will target this chain. The `--quorum` flag indicates the minimum number of nodes required to form a _consensus_. The recommended formula to obtain this number is `floor(N*2/3)+1` where `N` is the number of nodes in your committee. -The `--block-keep-amount` parameter determines how many blocks are stored in the [`blocklog`](/isc/../../../references/iota-chains/core-contracts/blocklog) core contract. +The `--block-keep-amount` parameter determines how many blocks are stored in the [`blocklog`](/isc/../../../references/iota-evm/core-contracts/blocklog) core contract. After deployment, the chain must be activated by the node operators of all peers. @@ -96,7 +96,7 @@ wasp-cli chain activate --chain= ## Test If It Works You can check that the chain was deployed correctly in the Wasp node dashboard (`/wasp/dashboard` when using `node-docker-setup`). -Note that the chain was deployed with some [core contracts](/isc/../../../references/iota-chains/core-contracts/overview). +Note that the chain was deployed with some [core contracts](/isc/../../../references/iota-evm/core-contracts/overview). You should also have an EVM-JSONRPC server opened on: diff --git a/docs/content/guides/operator/iota-chains-node/how-tos/wasp-cli.md b/docs/content/operator/iota-evm/how-tos/wasp-cli.md similarity index 100% rename from docs/content/guides/operator/iota-chains-node/how-tos/wasp-cli.md rename to docs/content/operator/iota-evm/how-tos/wasp-cli.md diff --git a/docs/content/guides/operator/iota-chains-node/reference/configuration.md b/docs/content/operator/iota-evm/reference/configuration.md similarity index 100% rename from docs/content/guides/operator/iota-chains-node/reference/configuration.md rename to docs/content/operator/iota-evm/reference/configuration.md diff --git a/docs/content/guides/operator/iota-chains-node/reference/metrics.md b/docs/content/operator/iota-evm/reference/metrics.md similarity index 100% rename from docs/content/guides/operator/iota-chains-node/reference/metrics.md rename to docs/content/operator/iota-evm/reference/metrics.md diff --git a/docs/content/references/iota-chains/.gitignore b/docs/content/references/iota-evm/.gitignore similarity index 100% rename from docs/content/references/iota-chains/.gitignore rename to docs/content/references/iota-evm/.gitignore diff --git a/docs/content/references/iota-chains/core-contracts/accounts.md b/docs/content/references/iota-evm/core-contracts/accounts.md similarity index 99% rename from docs/content/references/iota-chains/core-contracts/accounts.md rename to docs/content/references/iota-evm/core-contracts/accounts.md index 3f40ce25f79..90843b21c88 100644 --- a/docs/content/references/iota-chains/core-contracts/accounts.md +++ b/docs/content/references/iota-evm/core-contracts/accounts.md @@ -17,7 +17,7 @@ The `accounts` contract is one of the [core contracts](overview.md) on each IOTA chain. This contract keeps a consistent ledger of on-chain accounts in its state, -i.e. [the L2 ledger](../../../guides/developer/iota-chains/explanations/how-accounts-work.md). +i.e. [the L2 ledger](../../../developer/iota-evm/explanations/how-accounts-work.md). --- diff --git a/docs/content/references/iota-chains/core-contracts/blob.md b/docs/content/references/iota-evm/core-contracts/blob.md similarity index 100% rename from docs/content/references/iota-chains/core-contracts/blob.md rename to docs/content/references/iota-evm/core-contracts/blob.md diff --git a/docs/content/references/iota-chains/core-contracts/blocklog.md b/docs/content/references/iota-evm/core-contracts/blocklog.md similarity index 100% rename from docs/content/references/iota-chains/core-contracts/blocklog.md rename to docs/content/references/iota-evm/core-contracts/blocklog.md diff --git a/docs/content/references/iota-chains/core-contracts/errors.md b/docs/content/references/iota-evm/core-contracts/errors.md similarity index 100% rename from docs/content/references/iota-chains/core-contracts/errors.md rename to docs/content/references/iota-evm/core-contracts/errors.md diff --git a/docs/content/references/iota-chains/core-contracts/evm.md b/docs/content/references/iota-evm/core-contracts/evm.md similarity index 96% rename from docs/content/references/iota-chains/core-contracts/evm.md rename to docs/content/references/iota-evm/core-contracts/evm.md index 19257df3c7b..25aabe45503 100644 --- a/docs/content/references/iota-chains/core-contracts/evm.md +++ b/docs/content/references/iota-evm/core-contracts/evm.md @@ -20,11 +20,11 @@ tags: The `evm` contract is one of the [core contracts](overview.md) on each IOTA Smart Contracts chain. The `evm` core contract provides the necessary infrastructure to accept Ethereum transactions and execute EVM code. -It also includes the implementation of the [ISC Magic contract](../../../guides/developer/iota-chains/how-tos/core-contracts/introduction.md). +It also includes the implementation of the [ISC Magic contract](../../../developer/iota-evm/how-tos/core-contracts/introduction.md). :::note -For more information about how ISC supports EVM contracts, refer to the [EVM](../../../guides/developer/iota-chains/getting-started/languages-and-vms.mdx#evmsolidity-based-smart-contracts) section. +For more information about how ISC supports EVM contracts, refer to the [EVM](../../../developer/iota-evm/getting-started/languages-and-vms.mdx#evmsolidity-based-smart-contracts) section. ::: diff --git a/docs/content/references/iota-chains/core-contracts/governance.md b/docs/content/references/iota-evm/core-contracts/governance.md similarity index 100% rename from docs/content/references/iota-chains/core-contracts/governance.md rename to docs/content/references/iota-evm/core-contracts/governance.md diff --git a/docs/content/references/iota-chains/core-contracts/overview.md b/docs/content/references/iota-evm/core-contracts/overview.md similarity index 100% rename from docs/content/references/iota-chains/core-contracts/overview.md rename to docs/content/references/iota-evm/core-contracts/overview.md diff --git a/docs/content/references/iota-chains/core-contracts/root.md b/docs/content/references/iota-evm/core-contracts/root.md similarity index 100% rename from docs/content/references/iota-chains/core-contracts/root.md rename to docs/content/references/iota-evm/core-contracts/root.md diff --git a/docs/content/references/iota-chains/core-contracts/xfer.md b/docs/content/references/iota-evm/core-contracts/xfer.md similarity index 100% rename from docs/content/references/iota-chains/core-contracts/xfer.md rename to docs/content/references/iota-evm/core-contracts/xfer.md diff --git a/docs/content/references/iota-chains/json-rpc-spec.md b/docs/content/references/iota-evm/json-rpc-spec.md similarity index 100% rename from docs/content/references/iota-chains/json-rpc-spec.md rename to docs/content/references/iota-evm/json-rpc-spec.md diff --git a/docs/content/references/iota-chains/magic-contract/introduction.md b/docs/content/references/iota-evm/magic-contract/introduction.md similarity index 100% rename from docs/content/references/iota-chains/magic-contract/introduction.md rename to docs/content/references/iota-evm/magic-contract/introduction.md diff --git a/docs/content/references/iota-chains/wasm-lib-data-types.mdx b/docs/content/references/iota-evm/wasm-lib-data-types.mdx similarity index 87% rename from docs/content/references/iota-chains/wasm-lib-data-types.mdx rename to docs/content/references/iota-evm/wasm-lib-data-types.mdx index a0efcc72df5..b65983a3444 100644 --- a/docs/content/references/iota-chains/wasm-lib-data-types.mdx +++ b/docs/content/references/iota-evm/wasm-lib-data-types.mdx @@ -23,7 +23,7 @@ as human-readable text string. These are mostly simple built-in scalar data types as provided by most programming languages. Each integer data type has a clearly defined storage size. The -[Schema Tool](../../guides/developer/iota-chains/schema/how-tos/usage.mdx) will attempt to use the closest matching built-in data type when +[Schema Tool](../../developer/iota-evm/schema/how-tos/usage.mdx) will attempt to use the closest matching built-in data type when generating code for a specific language. - `BigInt` - An arbitrary-length unsigned integer. @@ -55,7 +55,7 @@ WasmLib provides its own implementations for each of the ISC value data types. ## Full Matrix of WasmLib Types -WasmLib implements a full set of [value proxies](../../guides/developer/iota-chains/schema/proxies.mdx#value-proxies) for each +WasmLib implements a full set of [value proxies](../../developer/iota-evm/schema/proxies.mdx#value-proxies) for each predefined value type that provide access to data on the ISC host. But there is one aspect of this data that we have not considered yet. Some data provided by the host is mutable, whereas other data may be immutable. To facilitate this distinction, each value proxy type @@ -97,8 +97,8 @@ The consistent naming makes it easy to remember the type names. Bool, Bytes, Str the integer types are the odd ones out. They are implemented in WasmLib by the closest equivalents in the chosen WasmLib implementation programming language. -The [Schema Tool](../../guides/developer/iota-chains/schema/how-tos/usage.mdx) will automatically generate the proper immutable proxies +The [Schema Tool](../../developer/iota-evm/schema/how-tos/usage.mdx) will automatically generate the proper immutable proxies from the schema definition. For example, View functions will only be able to access the -[State](../../guides/developer/iota-chains/schema/how-tos/state.mdx) map through immutable proxies. The same goes for the -[Params](../../guides/developer/iota-chains/schema/how-tos/params.mdx) map that was passed into a Func or View, and for the -[Results](../../guides/developer/iota-chains/schema/how-tos/results.mdx) map that was returned from a call to a Func or View. +[State](../../developer/iota-evm/schema/how-tos/state.mdx) map through immutable proxies. The same goes for the +[Params](../../developer/iota-evm/schema/how-tos/params.mdx) map that was passed into a Func or View, and for the +[Results](../../developer/iota-evm/schema/how-tos/results.mdx) map that was returned from a call to a Func or View. diff --git a/docs/content/sidebars/developer.js b/docs/content/sidebars/developer.js index 7c57b435c9c..ed9cad4a187 100644 --- a/docs/content/sidebars/developer.js +++ b/docs/content/sidebars/developer.js @@ -353,16 +353,16 @@ const developer = [ { type: 'category', - label: 'IOTA Chains', + label: 'Solidity/EVM Smart Contracts', link: { type: 'doc', - id: 'guides/developer/iota-chains/introduction', + id: 'developer/iota-evm/introduction', }, items: [ { type: 'doc', label: 'Introduction', - id: 'guides/developer/iota-chains/introduction', + id: 'developer/iota-evm/introduction', }, { type: 'category', @@ -371,19 +371,19 @@ const developer = [ { type: 'doc', label: 'Languages & VMs', - id: 'guides/developer/iota-chains/getting-started/languages-and-vms', + id: 'developer/iota-evm/getting-started/languages-and-vms', }, - 'guides/developer/iota-chains/getting-started/quick-start', - 'guides/developer/iota-chains/getting-started/compatibility', + 'developer/iota-evm/getting-started/quick-start', + 'developer/iota-evm/getting-started/compatibility', { type: 'doc', label: 'Networks & Chains', - id: 'guides/developer/iota-chains/getting-started/networks-and-chains', + id: 'developer/iota-evm/getting-started/networks-and-chains', }, { type: 'doc', label: 'Tools', - id: 'guides/developer/iota-chains/getting-started/tools', + id: 'developer/iota-evm/getting-started/tools', }, ], }, @@ -391,46 +391,46 @@ const developer = [ type: 'category', label: 'How To', items: [ - 'guides/developer/iota-chains/how-tos/introduction', + 'developer/iota-evm/how-tos/introduction', { type: 'doc', label: 'Send Funds from L1 to L2', - id: 'guides/developer/iota-chains/how-tos/send-funds-from-L1-to-L2', + id: 'developer/iota-evm/how-tos/send-funds-from-L1-to-L2', }, { type: 'doc', label: 'Create a Basic Contract', - id: 'guides/developer/iota-chains/how-tos/create-a-basic-contract', + id: 'developer/iota-evm/how-tos/create-a-basic-contract', }, { type: 'doc', label: 'Deploy a Smart Contract', - id: 'guides/developer/iota-chains/how-tos/deploy-a-smart-contract', + id: 'developer/iota-evm/how-tos/deploy-a-smart-contract', }, { type: 'doc', label: 'Create Custom Tokens - ERC20', - id: 'guides/developer/iota-chains/how-tos/ERC20', + id: 'developer/iota-evm/how-tos/ERC20', }, { type: 'doc', label: 'Send ERC20 Tokens Across Chains', - id: 'guides/developer/iota-chains/how-tos/send-ERC20-across-chains', + id: 'developer/iota-evm/how-tos/send-ERC20-across-chains', }, { type: 'doc', label: 'Create NFTs - ERC721', - id: 'guides/developer/iota-chains/how-tos/ERC721', + id: 'developer/iota-evm/how-tos/ERC721', }, { type: 'doc', label: 'Send NFTs Across Chains', - id: 'guides/developer/iota-chains/how-tos/send-NFTs-across-chains', + id: 'developer/iota-evm/how-tos/send-NFTs-across-chains', }, { type: 'doc', label: 'Test Smart Contracts', - id: 'guides/developer/iota-chains/how-tos/test-smart-contracts', + id: 'developer/iota-evm/how-tos/test-smart-contracts', }, { type: 'category', @@ -439,7 +439,7 @@ const developer = [ { type: 'doc', label: 'Introduction', - id: 'guides/developer/iota-chains/how-tos/core-contracts/introduction', + id: 'developer/iota-evm/how-tos/core-contracts/introduction', }, { type: 'category', @@ -448,7 +448,7 @@ const developer = [ { type: 'doc', label: 'Get Native Assets Balance', - id: 'guides/developer/iota-chains/how-tos/core-contracts/basics/get-balance', + id: 'developer/iota-evm/how-tos/core-contracts/basics/get-balance', }, { type: 'category', @@ -457,24 +457,24 @@ const developer = [ { type: 'doc', label: 'Allow', - id: 'guides/developer/iota-chains/how-tos/core-contracts/basics/allowance/allow', + id: 'developer/iota-evm/how-tos/core-contracts/basics/allowance/allow', }, { type: 'doc', label: 'Get Allowance', - id: 'guides/developer/iota-chains/how-tos/core-contracts/basics/allowance/get-allowance', + id: 'developer/iota-evm/how-tos/core-contracts/basics/allowance/get-allowance', }, { type: 'doc', label: 'Take Allowance', - id: 'guides/developer/iota-chains/how-tos/core-contracts/basics/allowance/take-allowance', + id: 'developer/iota-evm/how-tos/core-contracts/basics/allowance/take-allowance', }, ], }, { type: 'doc', label: 'Send Assets to L1', - id: 'guides/developer/iota-chains/how-tos/core-contracts/basics/send-assets-to-l1', + id: 'developer/iota-evm/how-tos/core-contracts/basics/send-assets-to-l1', }, ], }, @@ -485,32 +485,32 @@ const developer = [ { label: 'Introduction', type: 'doc', - id: 'guides/developer/iota-chains/how-tos/core-contracts/token/introduction', + id: 'developer/iota-evm/how-tos/core-contracts/token/introduction', }, { type: 'doc', label: 'Create a Native Token', - id: 'guides/developer/iota-chains/how-tos/core-contracts/token/create-native-token', + id: 'developer/iota-evm/how-tos/core-contracts/token/create-native-token', }, { type: 'doc', label: 'Mint Native Tokens', - id: 'guides/developer/iota-chains/how-tos/core-contracts/token/mint-token', + id: 'developer/iota-evm/how-tos/core-contracts/token/mint-token', }, { type: 'doc', label: 'Custom ERC20 Functions', - id: 'guides/developer/iota-chains/how-tos/core-contracts/token/erc20-native-token', + id: 'developer/iota-evm/how-tos/core-contracts/token/erc20-native-token', }, { type: 'doc', label: 'Create a Foundry', - id: 'guides/developer/iota-chains/how-tos/core-contracts/token/create-foundry', + id: 'developer/iota-evm/how-tos/core-contracts/token/create-foundry', }, { type: 'doc', label: 'Register Token as ERC20', - id: 'guides/developer/iota-chains/how-tos/core-contracts/token/register-token', + id: 'developer/iota-evm/how-tos/core-contracts/token/register-token', }, ], }, @@ -521,29 +521,29 @@ const developer = [ { label: 'Introduction', type: 'doc', - id: 'guides/developer/iota-chains/how-tos/core-contracts/nft/introduction', + id: 'developer/iota-evm/how-tos/core-contracts/nft/introduction', }, { type: 'doc', label: 'Mint an NFT', - id: 'guides/developer/iota-chains/how-tos/core-contracts/nft/mint-nft', + id: 'developer/iota-evm/how-tos/core-contracts/nft/mint-nft', }, { type: 'doc', label: 'Use as ERC721', - id: 'guides/developer/iota-chains/how-tos/core-contracts/nft/use-as-erc721', + id: 'developer/iota-evm/how-tos/core-contracts/nft/use-as-erc721', }, ], }, { type: 'doc', label: 'Get Randomness on L2', - id: 'guides/developer/iota-chains/how-tos/core-contracts/get-randomness-on-l2', + id: 'developer/iota-evm/how-tos/core-contracts/get-randomness-on-l2', }, { type: 'doc', label: 'Call and Call View', - id: 'guides/developer/iota-chains/how-tos/core-contracts/call-view', + id: 'developer/iota-evm/how-tos/core-contracts/call-view', }, ], }, @@ -556,47 +556,47 @@ const developer = [ { type: 'doc', label: 'Anatomy of a Smart Contract', - id: 'guides/developer/iota-chains/explanations/smart-contract-anatomy', + id: 'developer/iota-evm/explanations/smart-contract-anatomy', }, { type: 'doc', label: 'Sandbox Interface', - id: 'guides/developer/iota-chains/explanations/sandbox', + id: 'developer/iota-evm/explanations/sandbox', }, { type: 'doc', label: 'Calling a Smart Contract', - id: 'guides/developer/iota-chains/explanations/invocation', + id: 'developer/iota-evm/explanations/invocation', }, { type: 'doc', label: 'State, Transitions and State Anchoring', - id: 'guides/developer/iota-chains/explanations/states', + id: 'developer/iota-evm/explanations/states', }, { type: 'doc', label: 'State manager', - id: 'guides/developer/iota-chains/explanations/state_manager', + id: 'developer/iota-evm/explanations/state_manager', }, { type: 'doc', label: 'Validators and Access Nodes', - id: 'guides/developer/iota-chains/explanations/validators', + id: 'developer/iota-evm/explanations/validators', }, { type: 'doc', label: 'Consensus', - id: 'guides/developer/iota-chains/explanations/consensus', + id: 'developer/iota-evm/explanations/consensus', }, { type: 'doc', label: 'How Accounts Work', - id: 'guides/developer/iota-chains/explanations/how-accounts-work', + id: 'developer/iota-evm/explanations/how-accounts-work', }, { type: 'doc', label: 'Core Contracts', - id: 'references/iota-chains/core-contracts/overview', + id: 'references/iota-evm/core-contracts/overview', }, ], }, @@ -606,7 +606,7 @@ const developer = [ items: [ { label: 'Getting Started', - id: 'guides/developer/iota-chains/solo/getting-started', + id: 'developer/iota-evm/solo/getting-started', type: 'doc', }, { @@ -616,52 +616,52 @@ const developer = [ { type: 'doc', label: 'First Example', - id: 'guides/developer/iota-chains/solo/how-tos/first-example', + id: 'developer/iota-evm/solo/how-tos/first-example', }, { type: 'doc', label: 'The L1 Ledger', - id: 'guides/developer/iota-chains/solo/how-tos/the-l1-ledger', + id: 'developer/iota-evm/solo/how-tos/the-l1-ledger', }, { type: 'doc', label: 'Deploy a Smart Contract', - id: 'guides/developer/iota-chains/solo/how-tos/deploying-sc', + id: 'developer/iota-evm/solo/how-tos/deploying-sc', }, { type: 'doc', label: 'Invoke a Smart Contract', - id: 'guides/developer/iota-chains/solo/how-tos/invoking-sc', + id: 'developer/iota-evm/solo/how-tos/invoking-sc', }, { type: 'doc', label: 'Call a View', - id: 'guides/developer/iota-chains/solo/how-tos/view-sc', + id: 'developer/iota-evm/solo/how-tos/view-sc', }, { type: 'doc', label: 'Error Handling', - id: 'guides/developer/iota-chains/solo/how-tos/error-handling', + id: 'developer/iota-evm/solo/how-tos/error-handling', }, { type: 'doc', label: 'Accounts', - id: 'guides/developer/iota-chains/solo/how-tos/the-l2-ledger', + id: 'developer/iota-evm/solo/how-tos/the-l2-ledger', }, { type: 'doc', label: 'Test Smart Contracts', - id: 'guides/developer/iota-chains/solo/how-tos/test', + id: 'developer/iota-evm/solo/how-tos/test', }, { type: 'doc', label: 'Example Tests', - id: 'guides/developer/iota-chains/solo/how-tos/examples', + id: 'developer/iota-evm/solo/how-tos/examples', }, { type: 'doc', label: 'Colored Tokens and Time Locks', - id: 'guides/developer/iota-chains/solo/how-tos/timelock', + id: 'developer/iota-evm/solo/how-tos/timelock', }, ], }, @@ -674,12 +674,12 @@ const developer = [ { type: 'doc', label: 'The Schema Tool', - id: 'guides/developer/iota-chains/schema/introduction', + id: 'developer/iota-evm/schema/introduction', }, { type: 'doc', label: 'Data Access Proxies', - id: 'guides/developer/iota-chains/schema/proxies', + id: 'developer/iota-evm/schema/proxies', }, { type: 'category', @@ -688,82 +688,82 @@ const developer = [ { type: 'doc', label: 'Create a Schema', - id: 'guides/developer/iota-chains/schema/how-tos/usage', + id: 'developer/iota-evm/schema/how-tos/usage', }, { type: 'doc', label: 'Define the State', - id: 'guides/developer/iota-chains/schema/how-tos/state', + id: 'developer/iota-evm/schema/how-tos/state', }, { type: 'doc', label: 'Use Structured Data Types', - id: 'guides/developer/iota-chains/schema/how-tos/structs', + id: 'developer/iota-evm/schema/how-tos/structs', }, { type: 'doc', label: 'Generate Type Definitions', - id: 'guides/developer/iota-chains/schema/how-tos/typedefs', + id: 'developer/iota-evm/schema/how-tos/typedefs', }, { type: 'doc', label: 'Trigger Events', - id: 'guides/developer/iota-chains/schema/how-tos/events', + id: 'developer/iota-evm/schema/how-tos/events', }, { type: 'doc', label: 'Define Functions', - id: 'guides/developer/iota-chains/schema/how-tos/funcs', + id: 'developer/iota-evm/schema/how-tos/funcs', }, { type: 'doc', label: 'Limit Access', - id: 'guides/developer/iota-chains/schema/how-tos/access', + id: 'developer/iota-evm/schema/how-tos/access', }, { type: 'doc', label: 'Define Function Parameters', - id: 'guides/developer/iota-chains/schema/how-tos/params', + id: 'developer/iota-evm/schema/how-tos/params', }, { type: 'doc', label: 'Define Function Results', - id: 'guides/developer/iota-chains/schema/how-tos/results', + id: 'developer/iota-evm/schema/how-tos/results', }, { type: 'doc', label: 'Use Thunk Functions', - id: 'guides/developer/iota-chains/schema/how-tos/thunks', + id: 'developer/iota-evm/schema/how-tos/thunks', }, { type: 'doc', label: 'Use View-Only Functions', - id: 'guides/developer/iota-chains/schema/how-tos/views', + id: 'developer/iota-evm/schema/how-tos/views', }, { type: 'doc', label: 'Initialize a Smart Contract', - id: 'guides/developer/iota-chains/schema/how-tos/init', + id: 'developer/iota-evm/schema/how-tos/init', }, { type: 'doc', label: 'Transfer Tokens', - id: 'guides/developer/iota-chains/schema/how-tos/transfers', + id: 'developer/iota-evm/schema/how-tos/transfers', }, { type: 'doc', label: 'Add Function Descriptors', - id: 'guides/developer/iota-chains/schema/how-tos/funcdesc', + id: 'developer/iota-evm/schema/how-tos/funcdesc', }, { type: 'doc', label: 'Call Functions', - id: 'guides/developer/iota-chains/schema/how-tos/call', + id: 'developer/iota-evm/schema/how-tos/call', }, { type: 'doc', label: 'Post Asynchronous Requests', - id: 'guides/developer/iota-chains/schema/how-tos/post', + id: 'developer/iota-evm/schema/how-tos/post', }, ], }, diff --git a/docs/content/sidebars/operator.js b/docs/content/sidebars/operator.js index a019f0a2d78..8b04fb949a6 100644 --- a/docs/content/sidebars/operator.js +++ b/docs/content/sidebars/operator.js @@ -15,10 +15,10 @@ const operator = [ 'operator/node-tools', { type: 'category', - label: 'IOTA Chains Node', + label: 'IOTA EVM Network', link: { type: 'doc', - id: 'guides/operator/iota-chains-node/how-tos/running-a-node', + id: 'operator/iota-evm/how-tos/running-a-node', }, items: [ { @@ -28,26 +28,26 @@ const operator = [ items: [ { type: 'doc', - id: 'guides/operator/iota-chains-node/how-tos/running-a-node', + id: 'operator/iota-evm/how-tos/running-a-node', label: 'Run a Node', }, { type: 'doc', - id: 'guides/operator/iota-chains-node/how-tos/running-an-access-node', + id: 'operator/iota-evm/how-tos/running-an-access-node', label: 'Run an Access Node', }, { - id: 'guides/operator/iota-chains-node/how-tos/wasp-cli', + id: 'operator/iota-evm/how-tos/wasp-cli', label: 'Configure wasp-cli', type: 'doc', }, { - id: 'guides/operator/iota-chains-node/how-tos/setting-up-a-chain', + id: 'operator/iota-evm/how-tos/setting-up-a-chain', label: 'Set Up a Chain', type: 'doc', }, { - id: 'guides/operator/iota-chains-node/how-tos/chain-management', + id: 'operator/iota-evm/how-tos/chain-management', label: 'Manage a Chain', type: 'doc', }, @@ -59,11 +59,11 @@ const operator = [ items: [ { type: 'doc', - id: 'guides/operator/iota-chains-node/reference/configuration', + id: 'operator/iota-evm/reference/configuration', }, { type: 'doc', - id: 'guides/operator/iota-chains-node/reference/metrics', + id: 'operator/iota-evm/reference/metrics', }, ], }, diff --git a/docs/content/sidebars/references.js b/docs/content/sidebars/references.js index 6198f120dcc..4f36df8c3ba 100644 --- a/docs/content/sidebars/references.js +++ b/docs/content/sidebars/references.js @@ -229,16 +229,16 @@ const references = [ }, { type: 'category', - label: 'IOTA Chains', + label: 'IOTA EVM', items: [ - 'references/iota-chains/json-rpc-spec', + 'references/iota-evm/json-rpc-spec', { type: 'category', label: 'Magic Contract', items: [ { type: 'autogenerated', - dirName: 'references/iota-chains/magic-contract', + dirName: 'references/iota-evm/magic-contract', }, ], }, @@ -249,42 +249,42 @@ const references = [ { type: 'doc', label: 'Overview', - id: 'references/iota-chains/core-contracts/overview', + id: 'references/iota-evm/core-contracts/overview', }, { type: 'doc', label: 'root', - id: 'references/iota-chains/core-contracts/root', + id: 'references/iota-evm/core-contracts/root', }, { type: 'doc', label: 'accounts', - id: 'references/iota-chains/core-contracts/accounts', + id: 'references/iota-evm/core-contracts/accounts', }, { type: 'doc', label: 'blob', - id: 'references/iota-chains/core-contracts/blob', + id: 'references/iota-evm/core-contracts/blob', }, { type: 'doc', label: 'blocklog', - id: 'references/iota-chains/core-contracts/blocklog', + id: 'references/iota-evm/core-contracts/blocklog', }, { type: 'doc', label: 'governance', - id: 'references/iota-chains/core-contracts/governance', + id: 'references/iota-evm/core-contracts/governance', }, { type: 'doc', label: 'errors', - id: 'references/iota-chains/core-contracts/errors', + id: 'references/iota-evm/core-contracts/errors', }, { type: 'doc', label: 'EVM', - id: 'references/iota-chains/core-contracts/evm', + id: 'references/iota-evm/core-contracts/evm', }, ], }, @@ -294,14 +294,14 @@ const references = [ items: [ { type: 'autogenerated', - dirName: 'references/iota-chains/iscutils', + dirName: 'references/iota-evm/iscutils', }, ], }, { type: 'doc', label: 'WasmLib Data Types', - id: 'references/iota-chains/wasm-lib-data-types', + id: 'references/iota-evm/wasm-lib-data-types', }, ], }, diff --git a/docs/site/package.json b/docs/site/package.json index 97f047a8507..1dac08cd22e 100644 --- a/docs/site/package.json +++ b/docs/site/package.json @@ -4,8 +4,8 @@ "private": true, "scripts": { "docusaurus": "docusaurus", - "dev": "docusaurus graphql-to-doc; rm '../content/references/iota-api/iota-graphql/reference/generated.md'; node src/utils/getopenrpcspecs.js; git clean -Xdf ../content/references/iota-chains/; ./scripts/get-iota-chains-references.sh; docusaurus start", - "build": "docusaurus graphql-to-doc; rm '../content/references/iota-api/iota-graphql/reference/generated.md'; node src/utils/getopenrpcspecs.js; git clean -Xdf ../content/references/iota-chains/; ./scripts/get-iota-chains-references.sh; docusaurus build", + "dev": "docusaurus graphql-to-doc; rm '../content/references/iota-api/iota-graphql/reference/generated.md'; node src/utils/getopenrpcspecs.js; git clean -Xdf ../content/references/iota-evm/; ./scripts/get-iota-evm-references.sh; docusaurus start", + "build": "docusaurus graphql-to-doc; rm '../content/references/iota-api/iota-graphql/reference/generated.md'; node src/utils/getopenrpcspecs.js; git clean -Xdf ../content/references/iota-evm/; ./scripts/get-iota-evm-references.sh; docusaurus build", "swizzle": "docusaurus swizzle", "deploy": "docusaurus deploy", "clear": "docusaurus clear", diff --git a/docs/site/scripts/get-iota-chains-references.sh b/docs/site/scripts/get-iota-evm-references.sh similarity index 72% rename from docs/site/scripts/get-iota-chains-references.sh rename to docs/site/scripts/get-iota-evm-references.sh index 15d66890023..293cd23bba6 100755 --- a/docs/site/scripts/get-iota-chains-references.sh +++ b/docs/site/scripts/get-iota-evm-references.sh @@ -6,10 +6,10 @@ cd tmp # Download and copy docs curl -sL https://s3.eu-central-1.amazonaws.com/files.iota.org/iota-wiki/wasp/1.3/iscmagic.tar.gz | tar xzv -cp -Rv docs/iscmagic/* ../../content/references/iota-chains/magic-contract/ +cp -Rv docs/iscmagic/* ../../content/references/iota-evm/magic-contract/ curl -sL https://s3.eu-central-1.amazonaws.com/files.iota.org/iota-wiki/wasp/1.3/iscutils.tar.gz | tar xzv -cp -Rv docs/iscutils ../../content/references/iota-chains/ +cp -Rv docs/iscutils ../../content/references/iota-evm/ # Return to root and cleanup cd - diff --git a/docs/site/static/img/iota-chains/chain0.png b/docs/site/static/img/iota-evm/chain0.png similarity index 100% rename from docs/site/static/img/iota-chains/chain0.png rename to docs/site/static/img/iota-evm/chain0.png diff --git a/docs/site/static/img/iota-chains/chain1.png b/docs/site/static/img/iota-evm/chain1.png similarity index 100% rename from docs/site/static/img/iota-chains/chain1.png rename to docs/site/static/img/iota-evm/chain1.png diff --git a/docs/site/static/img/iota-chains/evm/examples/compile.png b/docs/site/static/img/iota-evm/evm/examples/compile.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/examples/compile.png rename to docs/site/static/img/iota-evm/evm/examples/compile.png diff --git a/docs/site/static/img/iota-chains/evm/examples/deploy-metamask.png b/docs/site/static/img/iota-evm/evm/examples/deploy-metamask.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/examples/deploy-metamask.png rename to docs/site/static/img/iota-evm/evm/examples/deploy-metamask.png diff --git a/docs/site/static/img/iota-chains/evm/examples/deploy.png b/docs/site/static/img/iota-evm/evm/examples/deploy.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/examples/deploy.png rename to docs/site/static/img/iota-evm/evm/examples/deploy.png diff --git a/docs/site/static/img/iota-chains/evm/examples/erc20-balance.png b/docs/site/static/img/iota-evm/evm/examples/erc20-balance.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/examples/erc20-balance.png rename to docs/site/static/img/iota-evm/evm/examples/erc20-balance.png diff --git a/docs/site/static/img/iota-chains/evm/examples/explorer-contract-address.png b/docs/site/static/img/iota-evm/evm/examples/explorer-contract-address.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/examples/explorer-contract-address.png rename to docs/site/static/img/iota-evm/evm/examples/explorer-contract-address.png diff --git a/docs/site/static/img/iota-chains/evm/how-tos/ERC20/metamask-erc20-balance.png b/docs/site/static/img/iota-evm/evm/how-tos/ERC20/metamask-erc20-balance.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/how-tos/ERC20/metamask-erc20-balance.png rename to docs/site/static/img/iota-evm/evm/how-tos/ERC20/metamask-erc20-balance.png diff --git a/docs/site/static/img/iota-chains/evm/how-tos/ERC20/metamask-get-transaction-or-go-to-block-explorer.png b/docs/site/static/img/iota-evm/evm/how-tos/ERC20/metamask-get-transaction-or-go-to-block-explorer.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/how-tos/ERC20/metamask-get-transaction-or-go-to-block-explorer.png rename to docs/site/static/img/iota-evm/evm/how-tos/ERC20/metamask-get-transaction-or-go-to-block-explorer.png diff --git a/docs/site/static/img/iota-chains/evm/how-tos/ERC20/metamask-import-tokens.png b/docs/site/static/img/iota-evm/evm/how-tos/ERC20/metamask-import-tokens.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/how-tos/ERC20/metamask-import-tokens.png rename to docs/site/static/img/iota-evm/evm/how-tos/ERC20/metamask-import-tokens.png diff --git a/docs/site/static/img/iota-chains/evm/how-tos/ERC721/confirm-in-metamask.png b/docs/site/static/img/iota-evm/evm/how-tos/ERC721/confirm-in-metamask.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/how-tos/ERC721/confirm-in-metamask.png rename to docs/site/static/img/iota-evm/evm/how-tos/ERC721/confirm-in-metamask.png diff --git a/docs/site/static/img/iota-chains/evm/how-tos/ERC721/safe-mint.png b/docs/site/static/img/iota-evm/evm/how-tos/ERC721/safe-mint.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/how-tos/ERC721/safe-mint.png rename to docs/site/static/img/iota-evm/evm/how-tos/ERC721/safe-mint.png diff --git a/docs/site/static/img/iota-chains/evm/how-tos/ERC721/set-initial-owner.png b/docs/site/static/img/iota-evm/evm/how-tos/ERC721/set-initial-owner.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/how-tos/ERC721/set-initial-owner.png rename to docs/site/static/img/iota-evm/evm/how-tos/ERC721/set-initial-owner.png diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/bloom-click-on-send.png b/docs/site/static/img/iota-evm/evm/how-tos/get-funds/bloom/bloom-click-on-send.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/bloom-click-on-send.png rename to docs/site/static/img/iota-evm/evm/how-tos/get-funds/bloom/bloom-click-on-send.png diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/bloom-review-and-confirm.png b/docs/site/static/img/iota-evm/evm/how-tos/get-funds/bloom/bloom-review-and-confirm.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/bloom-review-and-confirm.png rename to docs/site/static/img/iota-evm/evm/how-tos/get-funds/bloom/bloom-review-and-confirm.png diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/bloom-select-evm-account-1.png b/docs/site/static/img/iota-evm/evm/how-tos/get-funds/bloom/bloom-select-evm-account-1.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/bloom-select-evm-account-1.png rename to docs/site/static/img/iota-evm/evm/how-tos/get-funds/bloom/bloom-select-evm-account-1.png diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/bloom-select-the-desired-amount.png b/docs/site/static/img/iota-evm/evm/how-tos/get-funds/bloom/bloom-select-the-desired-amount.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/bloom-select-the-desired-amount.png rename to docs/site/static/img/iota-evm/evm/how-tos/get-funds/bloom/bloom-select-the-desired-amount.png diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/enter-the-amount.png b/docs/site/static/img/iota-evm/evm/how-tos/get-funds/bloom/enter-the-amount.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/enter-the-amount.png rename to docs/site/static/img/iota-evm/evm/how-tos/get-funds/bloom/enter-the-amount.png diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/enter-the-recipient-address.png b/docs/site/static/img/iota-evm/evm/how-tos/get-funds/bloom/enter-the-recipient-address.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/enter-the-recipient-address.png rename to docs/site/static/img/iota-evm/evm/how-tos/get-funds/bloom/enter-the-recipient-address.png diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/review-and-confirm-the-transaction.png b/docs/site/static/img/iota-evm/evm/how-tos/get-funds/bloom/review-and-confirm-the-transaction.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/review-and-confirm-the-transaction.png rename to docs/site/static/img/iota-evm/evm/how-tos/get-funds/bloom/review-and-confirm-the-transaction.png diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/select-send.png b/docs/site/static/img/iota-evm/evm/how-tos/get-funds/bloom/select-send.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/select-send.png rename to docs/site/static/img/iota-evm/evm/how-tos/get-funds/bloom/select-send.png diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/select-the-smr-token.png b/docs/site/static/img/iota-evm/evm/how-tos/get-funds/bloom/select-the-smr-token.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/how-tos/get-funds/bloom/select-the-smr-token.png rename to docs/site/static/img/iota-evm/evm/how-tos/get-funds/bloom/select-the-smr-token.png diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/copy-your-address.png b/docs/site/static/img/iota-evm/evm/how-tos/get-funds/copy-your-address.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/how-tos/get-funds/copy-your-address.png rename to docs/site/static/img/iota-evm/evm/how-tos/get-funds/copy-your-address.png diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/firefly/enter-your-desired-amount-and-metamask-address.png b/docs/site/static/img/iota-evm/evm/how-tos/get-funds/firefly/enter-your-desired-amount-and-metamask-address.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/how-tos/get-funds/firefly/enter-your-desired-amount-and-metamask-address.png rename to docs/site/static/img/iota-evm/evm/how-tos/get-funds/firefly/enter-your-desired-amount-and-metamask-address.png diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/firefly/hit-send.png b/docs/site/static/img/iota-evm/evm/how-tos/get-funds/firefly/hit-send.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/how-tos/get-funds/firefly/hit-send.png rename to docs/site/static/img/iota-evm/evm/how-tos/get-funds/firefly/hit-send.png diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/firefly/select-send-assets.png b/docs/site/static/img/iota-evm/evm/how-tos/get-funds/firefly/select-send-assets.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/how-tos/get-funds/firefly/select-send-assets.png rename to docs/site/static/img/iota-evm/evm/how-tos/get-funds/firefly/select-send-assets.png diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/firefly/select-shimmer-evm.png b/docs/site/static/img/iota-evm/evm/how-tos/get-funds/firefly/select-shimmer-evm.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/how-tos/get-funds/firefly/select-shimmer-evm.png rename to docs/site/static/img/iota-evm/evm/how-tos/get-funds/firefly/select-shimmer-evm.png diff --git a/docs/site/static/img/iota-chains/evm/remix-deployed.png b/docs/site/static/img/iota-evm/evm/remix-deployed.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/remix-deployed.png rename to docs/site/static/img/iota-evm/evm/remix-deployed.png diff --git a/docs/site/static/img/iota-chains/evm/remix-injected-provider-metamask.png b/docs/site/static/img/iota-evm/evm/remix-injected-provider-metamask.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/remix-injected-provider-metamask.png rename to docs/site/static/img/iota-evm/evm/remix-injected-provider-metamask.png diff --git a/docs/site/static/img/iota-chains/evm/remix-injected-provider-set.png b/docs/site/static/img/iota-evm/evm/remix-injected-provider-set.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/remix-injected-provider-set.png rename to docs/site/static/img/iota-evm/evm/remix-injected-provider-set.png diff --git a/docs/site/static/img/iota-chains/evm/remix-metamask-detail.png b/docs/site/static/img/iota-evm/evm/remix-metamask-detail.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/remix-metamask-detail.png rename to docs/site/static/img/iota-evm/evm/remix-metamask-detail.png diff --git a/docs/site/static/img/iota-chains/evm/remix-vm-injected.png b/docs/site/static/img/iota-evm/evm/remix-vm-injected.png similarity index 100% rename from docs/site/static/img/iota-chains/evm/remix-vm-injected.png rename to docs/site/static/img/iota-evm/evm/remix-vm-injected.png diff --git a/docs/site/static/img/iota-chains/multichain.png b/docs/site/static/img/iota-evm/multichain.png similarity index 100% rename from docs/site/static/img/iota-chains/multichain.png rename to docs/site/static/img/iota-evm/multichain.png diff --git a/docs/site/static/img/iota-chains/sandbox.png b/docs/site/static/img/iota-evm/sandbox.png similarity index 100% rename from docs/site/static/img/iota-chains/sandbox.png rename to docs/site/static/img/iota-evm/sandbox.png diff --git a/docs/site/static/img/iota-chains/tutorial/SC-structure.png b/docs/site/static/img/iota-evm/tutorial/SC-structure.png similarity index 100% rename from docs/site/static/img/iota-chains/tutorial/SC-structure.png rename to docs/site/static/img/iota-evm/tutorial/SC-structure.png diff --git a/docs/site/static/img/iota-chains/tutorial/accounts.png b/docs/site/static/img/iota-evm/tutorial/accounts.png similarity index 100% rename from docs/site/static/img/iota-chains/tutorial/accounts.png rename to docs/site/static/img/iota-evm/tutorial/accounts.png diff --git a/docs/site/static/img/iota-chains/tutorial/call_view.png b/docs/site/static/img/iota-evm/tutorial/call_view.png similarity index 100% rename from docs/site/static/img/iota-chains/tutorial/call_view.png rename to docs/site/static/img/iota-evm/tutorial/call_view.png diff --git a/docs/site/static/img/iota-chains/tutorial/send_request.png b/docs/site/static/img/iota-evm/tutorial/send_request.png similarity index 100% rename from docs/site/static/img/iota-chains/tutorial/send_request.png rename to docs/site/static/img/iota-evm/tutorial/send_request.png diff --git a/docs/site/static/img/iota-chains/wasm_vm/IscHost.png b/docs/site/static/img/iota-evm/wasm_vm/IscHost.png similarity index 100% rename from docs/site/static/img/iota-chains/wasm_vm/IscHost.png rename to docs/site/static/img/iota-evm/wasm_vm/IscHost.png diff --git a/docs/site/static/img/iota-chains/wasm_vm/Proxies.png b/docs/site/static/img/iota-evm/wasm_vm/Proxies.png similarity index 100% rename from docs/site/static/img/iota-chains/wasm_vm/Proxies.png rename to docs/site/static/img/iota-evm/wasm_vm/Proxies.png diff --git a/docs/site/static/img/iota-chains/wasm_vm/WasmVM.png b/docs/site/static/img/iota-evm/wasm_vm/WasmVM.png similarity index 100% rename from docs/site/static/img/iota-chains/wasm_vm/WasmVM.png rename to docs/site/static/img/iota-evm/wasm_vm/WasmVM.png From 69425ee7b9fc8749164fcd28a59472aee866c093 Mon Sep 17 00:00:00 2001 From: Jeroen van den Hout Date: Mon, 15 Jul 2024 12:12:08 +0200 Subject: [PATCH 22/37] fix(docs): fix relative paths --- .../iota-evm/explanations/core-contracts.md | 34 ++-- .../explanations/how-accounts-work.md | 9 +- .../iota-evm/explanations/invocation.mdx | 6 +- .../explanations/smart-contract-anatomy.md | 28 ++-- .../iota-evm/explanations/validators.md | 18 +-- .../iota-evm/getting-started/compatibility.md | 20 +-- .../getting-started/languages-and-vms.mdx | 50 +++--- .../getting-started/networks-and-chains.mdx | 30 ++-- .../iota-evm/getting-started/quick-start.mdx | 59 +++---- .../iota-evm/getting-started/tools.mdx | 89 +++++------ .../developer/iota-evm/how-tos/ERC20.mdx | 26 ++-- .../developer/iota-evm/how-tos/ERC721.mdx | 55 ++++--- .../basics/send-assets-to-l1.mdx | 18 +-- .../how-tos/core-contracts/call-view.md | 20 +-- .../how-tos/core-contracts/introduction.md | 26 ++-- .../how-tos/core-contracts/nft/mint-nft.mdx | 31 ++-- .../core-contracts/token/create-foundry.mdx | 21 +-- .../token/create-native-token.mdx | 50 +++--- .../core-contracts/token/mint-token.mdx | 17 +- .../core-contracts/token/register-token.mdx | 32 ++-- .../how-tos/create-a-basic-contract.mdx | 17 +- .../how-tos/deploy-a-smart-contract.mdx | 121 ++++++++------- .../how-tos/send-funds-from-L1-to-L2.mdx | 66 ++++---- .../developer/iota-evm/introduction.mdx | 15 +- .../iota-evm/schema/how-tos/state.mdx | 70 ++++----- .../iota-evm/schema/how-tos/typedefs.mdx | 146 +++++++++--------- .../iota-evm/solo/how-tos/error-handling.md | 14 +- .../iota-evm/solo/how-tos/first-example.md | 30 ++-- .../developer/iota-evm/solo/how-tos/test.mdx | 16 +- .../iota-evm/solo/how-tos/the-l2-ledger.md | 6 +- .../iota-evm/solo/how-tos/view-sc.md | 16 +- .../iota-evm/how-tos/chain-management.md | 14 +- .../iota-evm/how-tos/setting-up-a-chain.md | 18 +-- 33 files changed, 602 insertions(+), 586 deletions(-) diff --git a/docs/content/developer/iota-evm/explanations/core-contracts.md b/docs/content/developer/iota-evm/explanations/core-contracts.md index 272735574b0..e27fb2f0b5c 100644 --- a/docs/content/developer/iota-evm/explanations/core-contracts.md +++ b/docs/content/developer/iota-evm/explanations/core-contracts.md @@ -2,15 +2,15 @@ description: There currently are 6 core smart contracts that are always deployed on each chain, root, _default, accounts, blob, blocklog, and governance. image: /img/banner/banner_wasp_core_contracts_overview.png tags: - - smart contracts - - core - - initialization - - request handling - - on-chain ledger - - accounts - - data - - receipts - - reference + - smart contracts + - core + - initialization + - request handling + - on-chain ledger + - accounts + - data + - receipts + - reference --- # Core Contracts @@ -21,17 +21,17 @@ There are currently 7 core smart contracts that are always deployed on each chain. These are responsible for the vital functions of the chain and provide infrastructure for all other smart contracts: -- [`root`](../../../../references/iota-evm/core-contracts/root.md): Responsible for the initialization of the chain, maintains registry of deployed contracts. +- [`root`](../../../references/iota-evm/core-contracts/root.md): Responsible for the initialization of the chain, maintains registry of deployed contracts. -- [`accounts`](../../../../references/iota-evm/core-contracts/accounts.md): Manages the on-chain ledger of accounts. +- [`accounts`](../../../references/iota-evm/core-contracts/accounts.md): Manages the on-chain ledger of accounts. -- [`blob`](../../../../references/iota-evm/core-contracts/blob.md): Responsible for the registry of binary objects of arbitrary size. +- [`blob`](../../../references/iota-evm/core-contracts/blob.md): Responsible for the registry of binary objects of arbitrary size. -- [`blocklog`](../../../../references/iota-evm/core-contracts/blocklog.md): Keeps track of the blocks and receipts of requests that were processed by the chain. +- [`blocklog`](../../../references/iota-evm/core-contracts/blocklog.md): Keeps track of the blocks and receipts of requests that were processed by the chain. -- [`governance`](../../../../references/iota-evm/core-contracts/governance.md): Handles the administrative functions of the chain. For example: rotation of the committee of validators of the chain, fees and other chain-specific configurations. +- [`governance`](../../../references/iota-evm/core-contracts/governance.md): Handles the administrative functions of the chain. For example: rotation of the committee of validators of the chain, fees and other chain-specific configurations. -- [`errors`](../../../../references/iota-evm/core-contracts/errors.md): Keeps a map of error codes to error messages templates. These error codes are used in request receipts. +- [`errors`](../../../references/iota-evm/core-contracts/errors.md): Keeps a map of error codes to error messages templates. These error codes are used in request receipts. -- [`evm`](../../../../references/iota-evm/core-contracts/evm.md): Provides the necessary infrastructure to accept Ethereum - transactions and execute EVM code. +- [`evm`](../../../references/iota-evm/core-contracts/evm.md): Provides the necessary infrastructure to accept Ethereum + transactions and execute EVM code. diff --git a/docs/content/developer/iota-evm/explanations/how-accounts-work.md b/docs/content/developer/iota-evm/explanations/how-accounts-work.md index 0155bf39065..cb0834d9795 100644 --- a/docs/content/developer/iota-evm/explanations/how-accounts-work.md +++ b/docs/content/developer/iota-evm/explanations/how-accounts-work.md @@ -11,6 +11,7 @@ tags: - explanation --- + # How Accounts Work On the L1 Ledger, like with any _DLT_, we have **trustless** and **atomic** transfers of assets between addresses on the @@ -74,12 +75,12 @@ Tokens in an Ethereum account can only be moved by sending an Ethereum transacti ## The Accounts Contract -The [`accounts` core contract](../../../../references/iota-evm/core-contracts/accounts.md) is responsible for managing the L2 ledger. +The [`accounts` core contract](../../../references/iota-evm/core-contracts/accounts.md) is responsible for managing the L2 ledger. By calling this contract, it is possible to: -- [View current account balances](../how-tos/core-contracts/basics/get-balance.md) -- [Deposit funds to the chain](../how-tos/send-funds-from-L1-to-L2.mdx) -- [Withdraw funds from the chain](../how-tos/core-contracts/basics/send-assets-to-l1.mdx) +- [View current account balances](../how-tos/core-contracts/basics/get-balance.md) +- [Deposit funds to the chain](../how-tos/send-funds-from-L1-to-L2.mdx) +- [Withdraw funds from the chain](../how-tos/core-contracts/basics/send-assets-to-l1.mdx) ## Example diff --git a/docs/content/developer/iota-evm/explanations/invocation.mdx b/docs/content/developer/iota-evm/explanations/invocation.mdx index de8fc7ff256..b3599d33294 100644 --- a/docs/content/developer/iota-evm/explanations/invocation.mdx +++ b/docs/content/developer/iota-evm/explanations/invocation.mdx @@ -14,7 +14,7 @@ tags: --- -import OnOffLedgerRequest from '../../../../_snippets/iota-evm/on_off_ledger_request.md'; +import OnOffLedgerRequest from '../../../_snippets/iota-evm/on_off_ledger_request.md'; # Calling a Smart Contract @@ -65,7 +65,7 @@ exchange which would will the user's funds from one currency to another and send This is called _asynchronous composability_. - + --- @@ -78,7 +78,7 @@ as token swaps can require more due to the higher computational work involved. For users to specify how much they're willing to pay for a request, they need to specify a `GasBudget` in the request. This gas budget is the "maximum operations that this request can execute" and will be charged as a fee based on the -chain's current [fee policy](../../../../references/iota-evm/core-contracts/governance.md#fee-policy). +chain's current [fee policy](../../../references/iota-evm/core-contracts/governance.md#fee-policy). The funds to cover the gas used will be charged directly from the user's on-chain account. diff --git a/docs/content/developer/iota-evm/explanations/smart-contract-anatomy.md b/docs/content/developer/iota-evm/explanations/smart-contract-anatomy.md index 2da2952c532..a558da3cc6d 100644 --- a/docs/content/developer/iota-evm/explanations/smart-contract-anatomy.md +++ b/docs/content/developer/iota-evm/explanations/smart-contract-anatomy.md @@ -2,12 +2,12 @@ description: Each smart contract instance has a program with a collection of entry points and a state. image: /img/iota-evm/tutorial/SC-structure.png tags: - - smart contracts - - structure - - state - - entry points - - Wasm - - explanation + - smart contracts + - structure + - state + - entry points + - Wasm + - explanation --- # Anatomy of a Smart Contract @@ -23,9 +23,9 @@ contracts coexisting on the same chain. ## Identifying a Smart Contract -The ISC [core contracts](core-contracts.md) and WASM contracts on the chain are identified by a _hname_ (pronounced +The ISC [core contracts](core-contracts.md) and WASM contracts on the chain are identified by a _hname_ (pronounced "aitch-name"), which is a `uint32` value calculated as a hash of the smart contract's instance name (a string). -For example, the hname of the [`root`](../../../../references/iota-evm/core-contracts/root.md) core contract +For example, the hname of the [`root`](../../../references/iota-evm/core-contracts/root.md) core contract is `0xcebf5908`. This value uniquely identifies this contract in every chain. This does not apply to EVM contracts. ## State @@ -56,16 +56,16 @@ An entry point is a function through which you can invoke the program. There are two types of entry points: -- _Full entry points_ (or simply _entry points_): These functions can modify - (mutate) the smart contract's state. -- _View entry points_ (or _views_): These are read-only functions. They are only used - to retrieve the information from the smart contract state. They cannot - modify the state, i.e., they are read-only calls. +- _Full entry points_ (or simply _entry points_): These functions can modify + (mutate) the smart contract's state. +- _View entry points_ (or _views_): These are read-only functions. They are only used + to retrieve the information from the smart contract state. They cannot + modify the state, i.e., they are read-only calls. ## Execution Results After a request to a Smart Contract is executed (a call to a full entry point), a _receipt_ will be added to -the [`blocklog`](../../../../references/iota-evm/core-contracts/blocklog.md) core contract. The receipt details the +the [`blocklog`](../../../references/iota-evm/core-contracts/blocklog.md) core contract. The receipt details the execution results of said request: whether it was successful, the block it was included in, and other information. Any events dispatched by the smart contract in context of this execution will also be added to the receipt. diff --git a/docs/content/developer/iota-evm/explanations/validators.md b/docs/content/developer/iota-evm/explanations/validators.md index 11be09533be..5583dbc0421 100644 --- a/docs/content/developer/iota-evm/explanations/validators.md +++ b/docs/content/developer/iota-evm/explanations/validators.md @@ -2,12 +2,12 @@ description: Each chain is run by a network of validator nodes which run a consensus on the chain state update. image: /img/logo/WASP_logo_dark.png tags: - - validators - - validator nodes - - access nodes - - consensus - - state update - - explanation + - validators + - validator nodes + - access nodes + - consensus + - state update + - explanation --- # Validators @@ -39,11 +39,11 @@ account. Any node can optionally provide access to smart contracts for external callers, allowing them to: -- Query the state of the chain (i.e., _view calls_) -- Send off-ledger requests directly to the node (instead of sending an on-ledger request as a L1 transaction) +- Query the state of the chain (i.e., _view calls_) +- Send off-ledger requests directly to the node (instead of sending an on-ledger request as a L1 transaction) It is common for validator nodes to be part of a private subnet and have only a group of access nodes exposed to the outside world, protecting the committee from external attacks. The management of validator and access nodes is done through -the [`governance` core contract](../../../../references/iota-evm/core-contracts/governance.md). +the [`governance` core contract](../../../references/iota-evm/core-contracts/governance.md). diff --git a/docs/content/developer/iota-evm/getting-started/compatibility.md b/docs/content/developer/iota-evm/getting-started/compatibility.md index 30e9a532448..363919295b0 100644 --- a/docs/content/developer/iota-evm/getting-started/compatibility.md +++ b/docs/content/developer/iota-evm/getting-started/compatibility.md @@ -2,19 +2,19 @@ description: Compatibility between the ISC EVM layer and existing Ethereum smart contracts and tooling. image: /img/logo/WASP_logo_dark.png tags: - - smart contracts - - EVM - - Ethereum - - Solidity - - limitations - - compatibility - - fees - - reference + - smart contracts + - EVM + - Ethereum + - Solidity + - limitations + - compatibility + - fees + - reference --- # EVM Compatibility in IOTA Smart Contracts -The [`evm`](../../../../references/iota-evm/core-contracts/evm.md) [core contract](../../../../references/iota-evm/core-contracts/overview.md) +The [`evm`](../../../references/iota-evm/core-contracts/evm.md) [core contract](../../../references/iota-evm/core-contracts/overview.md) provides EVM support in IOTA Smart Contracts. It stores the EVM state (account balances, state, code, etc.) and provides a way to execute EVM code to manipulate the state. @@ -34,7 +34,7 @@ Here are some of the most important properties and limitations of EVM support in ### No Enforced Block Time There is no guaranteed _block time_. A new EVM "block" will be created only when an ISC block is created, and ISC does -not enforce an average block time. This means that block times are variable; a new block will be created as soon as needed. +not enforce an average block time. This means that block times are variable; a new block will be created as soon as needed. ### The Magic Contract diff --git a/docs/content/developer/iota-evm/getting-started/languages-and-vms.mdx b/docs/content/developer/iota-evm/getting-started/languages-and-vms.mdx index 5be2c353530..35bdbf43732 100644 --- a/docs/content/developer/iota-evm/getting-started/languages-and-vms.mdx +++ b/docs/content/developer/iota-evm/getting-started/languages-and-vms.mdx @@ -2,22 +2,22 @@ description: Compatibility between languages and different virtual machines. image: /img/logo/WASP_logo_dark.png tags: - - smart contracts - - EVM - - Ethereum - - Solidity - - limitations - - compatibility - - reference + - smart contracts + - EVM + - Ethereum + - Solidity + - limitations + - compatibility + - reference --- -import EVMCompatibility from '../../../../_snippets/iota-evm/EVM_compatibility.md' +import EVMCompatibility from '../../../_snippets/iota-evm/EVM_compatibility.md'; # Supported Virtual Machines & Languages The current release of IOTA Smart Contracts has support for [EVM/Solidity](#evmsolidity-based-smart-contracts) smart contracts, as well as experimental [Wasm](#wasm-vm-for-isc) smart contracts, providing compatibility with -existing smart contracts and tooling from other EVM based chains like Ethereum. This allows us to offer the existing +existing smart contracts and tooling from other EVM based chains like Ethereum. This allows us to offer the existing ecosystem around EVM/Solidity a familiar alternative. ## EVM Smart Contracts @@ -31,13 +31,13 @@ tested virtual machine running most smart contract networks. specific purpose. The main benefit of using EVM/Solidity is its sheer amount of resources from years of development. The IOTA -Smart Contracts implementation is fully compatible with all of them. If you have experience developing on other EVM based chains, you will feel right at home. Any existing contracts you've written will need no +Smart Contracts implementation is fully compatible with all of them. If you have experience developing on other EVM based chains, you will feel right at home. Any existing contracts you've written will need no changes to function on IOTA Smart Contracts. ### How IOTA Smart Contracts Work With EVM Every deployed ISC chain automatically includes a core contract -called [`evm`](../../../../references/iota-evm/core-contracts/evm.md). This core contract is responsible for running EVM code and +called [`evm`](../../../references/iota-evm/core-contracts/evm.md). This core contract is responsible for running EVM code and storing the EVM state. The Wasp node also provides a standard JSON-RPC service, which allows you to interact with the EVM layer using existing @@ -56,14 +56,14 @@ Experiment but avoid using it for production applications; opt for [EVM](quick-s ::: -IOTA Smart Contracts (ISC) provide a sandboxed environment through an API, facilitating secure and deterministic -interactions with ISC functions. This API supports any Virtual Machine (VM) aiming to build a system for smart contract - code execution on ISC. +IOTA Smart Contracts (ISC) provide a sandboxed environment through an API, facilitating secure and deterministic +interactions with ISC functions. This API supports any Virtual Machine (VM) aiming to build a system for smart contract +code execution on ISC. ![Wasp node ISC Host](/img/iota-evm/wasm_vm/IscHost.png) You can use a [WebAssembly (Wasm)](https://webassembly.org/) VM as a compilation target, facilitated by the open-source -[Wasmtime runtime](https://wasmtime.dev/). This setup encourages dynamic smart contract operations compiled to Wasm code, +[Wasmtime runtime](https://wasmtime.dev/). This setup encourages dynamic smart contract operations compiled to Wasm code, promoting security and adaptability with different programming languages. ![Wasm VM](/img/iota-evm/wasm_vm/WasmVM.png) @@ -75,23 +75,23 @@ functionality and smart contract state storage access. The ISC sandbox environment offers: -- Smart contract metadata and state data access. -- Request data retrieval for function calls. -- Token management within the contract. -- Utility functions from the host. -- Smooth initiation of other smart contract functions. -- Logging facility. +- Smart contract metadata and state data access. +- Request data retrieval for function calls. +- Token management within the contract. +- Utility functions from the host. +- Smooth initiation of other smart contract functions. +- Logging facility. ### Supported Languages -The WasmLib started with [Rust](https://www.rust-lang.org/) support, expanding to include [Go](https://golang.org/) +The WasmLib started with [Rust](https://www.rust-lang.org/) support, expanding to include [Go](https://golang.org/) and [TypeScript](https://www.typescriptlang.org/) with the help of respective Wasm code generators: | Language | Wasm code generator | -|------------|----------------------------------------------------| +| ---------- | -------------------------------------------------- | | Go | [TinyGo](https://tinygo.org/) | | Rust | [wasm-pack](https://rustwasm.github.io/wasm-pack/) | | TypeScript | [AssemblyScript](https://www.assemblyscript.org/) | -These generators maintain a common subset of their host language, aiming for a unified coding style to simplify the -initiation into smart contract creation, welcoming developers with a C-style language background to quickly adapt. \ No newline at end of file +These generators maintain a common subset of their host language, aiming for a unified coding style to simplify the +initiation into smart contract creation, welcoming developers with a C-style language background to quickly adapt. diff --git a/docs/content/developer/iota-evm/getting-started/networks-and-chains.mdx b/docs/content/developer/iota-evm/getting-started/networks-and-chains.mdx index d4d42a67d2d..2dc3364ef3c 100644 --- a/docs/content/developer/iota-evm/getting-started/networks-and-chains.mdx +++ b/docs/content/developer/iota-evm/getting-started/networks-and-chains.mdx @@ -1,18 +1,20 @@ --- description: Networks and endpoints in the IOTA ecosystem. tags: - - mainnet - - shimmer - - devnet - - EVM Testnet - - reference - - Endpoints + - mainnet + - shimmer + - devnet + - EVM Testnet + - reference + - Endpoints --- + import { AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; import { Networks } from '@theme/constant'; import NetworkInfo from '@theme/NetworkInfo'; # Networks & Chains + ## IOTA EVM Testnet @@ -41,11 +43,11 @@ The other values (network name and currency symbol) can be whatever value you li - + ### Additional Info - + ## IOTA EVM Testnet @@ -70,7 +72,7 @@ The other values (network name and currency symbol) can be whatever value you li ### Additional Info - + ## ShimmerEVM Testnet @@ -96,7 +98,7 @@ The other values (network name and currency symbol) can be whatever value you li ### Additional Info - + ## ShimmerEVM @@ -108,7 +110,7 @@ The other values (network name and currency symbol) can be whatever value you li ### Additional Info - + ## ShimmerEVM Testnet @@ -134,10 +136,10 @@ The other values (network name and currency symbol) can be whatever value you li ### Additional Info - + ## Core Contracts [IOTA EVM](#IOTAEVM), [ShimmerEVM](#shimmerEVM) and the testnet networks have 7 -[core contracts](../../../../references/iota-evm/core-contracts/overview.md) deployed, as well as the -[Magic Contract](../../../../references/iota-evm/magic-contract/introduction.md). +[core contracts](../../../references/iota-evm/core-contracts/overview.md) deployed, as well as the +[Magic Contract](../../../references/iota-evm/magic-contract/introduction.md). diff --git a/docs/content/developer/iota-evm/getting-started/quick-start.mdx b/docs/content/developer/iota-evm/getting-started/quick-start.mdx index 7a623a318a4..eb8d72976fe 100644 --- a/docs/content/developer/iota-evm/getting-started/quick-start.mdx +++ b/docs/content/developer/iota-evm/getting-started/quick-start.mdx @@ -2,18 +2,19 @@ description: This guide will help you quickly get started with the EVM image: /img/logo/WASP_logo_dark.png tags: - - quickstart - - developer - - using - - EVM - - Ethereum - - Solidity - - metamask - - JSON - - RPC + - quickstart + - developer + - using + - EVM + - Ethereum + - Solidity + - metamask + - JSON + - RPC --- -import DeployAdmonition from '../../../../_snippets/iota-evm/deploy_a_smart_contract.md'; -import MetamaskButtons from '../../../../_snippets/iota-evm/metamask_buttons.mdx'; + +import DeployAdmonition from '../../../_snippets/iota-evm/deploy_a_smart_contract.md'; +import MetamaskButtons from '../../../_snippets/iota-evm/metamask_buttons.mdx'; import { Networks } from '@theme/constant'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; @@ -25,17 +26,17 @@ This guide will help you quickly get started with our EVM, where you can deploy ## Prerequisites -- [MetaMask](https://metamask.io/) browser extension installed +- [MetaMask](https://metamask.io/) browser extension installed ## Setup MetaMask Click this button: - + :::tip -Please read [the MetaMask section in the tools guide](tools.mdx#metamask) for a detailed guide. +Please read [the MetaMask section in the tools guide](tools.mdx#metamask) for a detailed guide. ::: @@ -60,24 +61,24 @@ You can now deploy and interact with smart contracts. Utilize popular developmen Visit the corresponding Block Explorer to monitor the chain, track transactions, and explore deployed smart contracts. - - -Explorer - - -Explorer - - -Explorer - - -Explorer - + + + Explorer + + + Explorer + + + Explorer + + + Explorer + ## Additional Resources -- [GitHub issues page for Wasp](https://github.com/iotaledger/wasp/issues) -- [Firefly](https://firefly.iota.org) +- [GitHub issues page for Wasp](https://github.com/iotaledger/wasp/issues) +- [Firefly](https://firefly.iota.org) With this quickstart guide, you should now be able to set up and start exploring the EVM. As you begin to deploy and interact with smart contracts, remember to provide feedback on any issues or improvements you discover to help make our EVM even better. Happy developing! diff --git a/docs/content/developer/iota-evm/getting-started/tools.mdx b/docs/content/developer/iota-evm/getting-started/tools.mdx index ed8a57bd7f1..5420c5e337e 100644 --- a/docs/content/developer/iota-evm/getting-started/tools.mdx +++ b/docs/content/developer/iota-evm/getting-started/tools.mdx @@ -16,15 +16,16 @@ tags: - reference --- + import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -import {AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; -import HardhatConfig from '../../../../_snippets/iota-evm/hardhat_config.mdx'; +import { AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; +import HardhatConfig from '../../../_snippets/iota-evm/hardhat_config.mdx'; import { Networks } from '@theme/constant'; -import DeployAdmonition from '../../../../_snippets/iota-evm/deploy_a_smart_contract.md'; +import DeployAdmonition from '../../../_snippets/iota-evm/deploy_a_smart_contract.md'; import { ChainId } from '@theme/ChainId'; import NetworkInfo from '@theme/NetworkInfo'; -import OraclesContractData from '../../../../_snippets/iota-evm/oracles_contract_data.mdx'; +import OraclesContractData from '../../../_snippets/iota-evm/oracles_contract_data.mdx'; # Compatible Tools @@ -34,10 +35,10 @@ directly with an IOTA Smart Contracts chain running EVM as long as you take a co ## Tooling Considerations 1. Please make sure you use the correct JSON-RPC endpoint URL in your tooling for your chain. If you're running your own chain, you can find the JSON-RPC -endpoint URL in the Wasp dashboard (`[URL]/wasp/dashboard` when using `node-docker-setup`). + endpoint URL in the Wasp dashboard (`[URL]/wasp/dashboard` when using `node-docker-setup`). 2. Please ensure you use the correct `Chain ID` configured while starting the JSON-RPC service. If you did not explicitly define this while starting the service, the default Chain ID will be -for IOTA EVM, -for ShimmerEVM or for the EVM Testnet. + for IOTA EVM, + for ShimmerEVM or for the EVM Testnet. 3. Fees are handled on the IOTA Smart Contracts chain level, not the EVM level. The chain will reject any requests with a different gas price than specified by the chain. :::caution @@ -50,23 +51,23 @@ chain ID after deployment.** ## Network RPCs - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + ## IOTA EVM Tools @@ -117,23 +118,23 @@ To use your EVM chain with MetaMask, simply open up MetaMask and click on the ne the bottom of this list, you will see the option `Add network`. On the new page you will see a list of popular network with the option `Add a network manually`. For example this would be the configs to add our different EVM chains: - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + Ensure that your `RPC Url` and `Chain ID` are set correctly and match the dashboard values. The `Network Name` can be @@ -153,7 +154,7 @@ the `Environment` dropdown. ![Select Injected Provider from the Environment dropdown](/img/iota-evm/evm/remix-injected-provider-metamask.png) - + Metamask will ask to connect to Remix, and once connected, it will set the `Environment` to `Injected Web3` with the "Custom (Chain ID) network". @@ -166,9 +167,9 @@ the "Custom (Chain ID) network". Solidity smart contracts on an EVM chain. EVM chains running on IOTA Smart Contracts are compatible with Hardhat; simply make sure you add the correct network parameters to your `hardhat.config.js`, for example: - + - + :::caution diff --git a/docs/content/developer/iota-evm/how-tos/ERC20.mdx b/docs/content/developer/iota-evm/how-tos/ERC20.mdx index cdc49431724..127cf7a5cbc 100644 --- a/docs/content/developer/iota-evm/how-tos/ERC20.mdx +++ b/docs/content/developer/iota-evm/how-tos/ERC20.mdx @@ -2,19 +2,19 @@ description: Solidity smart contract ERC20. image: /img/logo/WASP_logo_dark.png tags: - - smart contracts - - EVM - - Solidity - - ERC20 - - eip-20 - - token creation - - mint tokens - - how to + - smart contracts + - EVM + - Solidity + - ERC20 + - eip-20 + - token creation + - mint tokens + - how to --- -import DeployAdmonition from '../../../../_snippets/iota-evm/deploy_a_smart_contract.md'; -import PriorKnowledge from '../../../../_snippets/iota-evm/EVM-required-prior-knowledge.md'; -import RemixIDE from '../../../../_snippets/iota-evm/remix-IDE.md'; +import DeployAdmonition from '../../../_snippets/iota-evm/deploy_a_smart_contract.md'; +import PriorKnowledge from '../../../_snippets/iota-evm/EVM-required-prior-knowledge.md'; +import RemixIDE from '../../../_snippets/iota-evm/remix-IDE.md'; # Create ERC20 Custom Tokens @@ -66,7 +66,7 @@ You can change the token name `ExampleERC20Token` and the token symbol `EET` for ::: - + ## 2. Add Your Custom Tokens to MetaMask @@ -76,7 +76,7 @@ Once you have deployed your contract, you can add your new custom token to your on `View on block explorer` to visit the transaction details. Alternatively, you can copy the transaction ID and visit the [IOTA EVM Explorer](https://explorer.evm.iota.org), [ShimmerEVM Explorer](https://explorer.evm.testnet.shimmer.network/) - or [EVM Testnet Explorer](https://explorer.evm.testnet.shimmer.network/) and use the search bar to find transaction. + or [EVM Testnet Explorer](https://explorer.evm.testnet.shimmer.network/) and use the search bar to find transaction. !['View on block explorer](/img/iota-evm/evm/how-tos/ERC20/metamask-get-transaction-or-go-to-block-explorer.png) diff --git a/docs/content/developer/iota-evm/how-tos/ERC721.mdx b/docs/content/developer/iota-evm/how-tos/ERC721.mdx index 6b3d80000e8..75144ab82b4 100644 --- a/docs/content/developer/iota-evm/how-tos/ERC721.mdx +++ b/docs/content/developer/iota-evm/how-tos/ERC721.mdx @@ -2,18 +2,19 @@ description: Create and deploy a Solidity smart contract to mint NFTs using the ERC721 standard. image: /img/iota-evm/evm/ozw-721.png tags: - - smart contracts - - EVM - - Solidity - - ERC721 - - eip-721 - - token creation - - mint tokens - - how to + - smart contracts + - EVM + - Solidity + - ERC721 + - eip-721 + - token creation + - mint tokens + - how to --- -import DeployAdmonition from '../../../../_snippets/iota-evm/deploy_a_smart_contract.md'; -import PriorKnowledge from '../../../../_snippets/iota-evm/EVM-required-prior-knowledge.md'; -import RemixIDE from '../../../../_snippets/iota-evm/remix-IDE.md'; + +import DeployAdmonition from '../../../_snippets/iota-evm/deploy_a_smart_contract.md'; +import PriorKnowledge from '../../../_snippets/iota-evm/EVM-required-prior-knowledge.md'; +import RemixIDE from '../../../_snippets/iota-evm/remix-IDE.md'; # Create ERC721 NFTs @@ -72,17 +73,17 @@ contract IotaEVMSampleNFT is ERC721, Ownable { As you can see above, the contract uses standard methods for the most part. You should pay attention to the following: -- `pragma solidity ^0.8.20;`: This line means the contract uses solidity compiler version `0.8.20` or above. -- `contract IotaEVMSampleNFT is ERC721, ERC721URIStorage, Ownable`: This line defines the contract's name, and what - other contracts it implements. -- `ERC721("IotaEVMSampleNFT", "SNFT") {}`: This line defines the token name and symbol. You can name it - whatever you want. We recommend using the same name for the token and the contract. -- `return "https://example.com/nft/";`: You should define the base URI of your NFTs. That means the URL you provide here - will be used for all your tokens. Since this contract uses auto-incremental token IDs, your token URI will look - something like `https://example.com/nft/0`, `https://example.com/nft/1`, `https://example.com/nft/2`, and so on. -- `function safeMint(address to, string memory uri) public onlyOwner {`: The `safeMint` function will - require that you manually input a token's `to` address and a `uri` every time you want to mint. This should work for - regular use cases. +- `pragma solidity ^0.8.20;`: This line means the contract uses solidity compiler version `0.8.20` or above. +- `contract IotaEVMSampleNFT is ERC721, ERC721URIStorage, Ownable`: This line defines the contract's name, and what + other contracts it implements. +- `ERC721("IotaEVMSampleNFT", "SNFT") {}`: This line defines the token name and symbol. You can name it + whatever you want. We recommend using the same name for the token and the contract. +- `return "https://example.com/nft/";`: You should define the base URI of your NFTs. That means the URL you provide here + will be used for all your tokens. Since this contract uses auto-incremental token IDs, your token URI will look + something like `https://example.com/nft/0`, `https://example.com/nft/1`, `https://example.com/nft/2`, and so on. +- `function safeMint(address to, string memory uri) public onlyOwner {`: The `safeMint` function will + require that you manually input a token's `to` address and a `uri` every time you want to mint. This should work for + regular use cases. ### Customize on OpenZeppelin @@ -98,7 +99,6 @@ and questions: You can click on `Copy to Clipboard` and paste it into the IDE of your choice, download it, or click on `Open in Remix` directly. - :::note Set the Initial Owner Before you can deploy this contract, you will need to set the `Initial Owner` address; this can be your own IOTA EVM address. @@ -107,7 +107,7 @@ Before you can deploy this contract, you will need to set the `Initial Owner` ad ::: - + ### Mint Your Custom NFTs @@ -116,14 +116,13 @@ To do, you should: 1. Open the contract (listed under `Deployed Contracts`). 2. Insert your target IOTA EVM in beside the `safeMint` button and then click the button. - + ![Safe mint](/img/iota-evm/evm/how-tos/ERC721/safe-mint.png) 3. Confirm the transaction on Metamask. - ![Confirm in metamask](/img/iota-evm/evm/how-tos/ERC721/confirm-in-metamask.png) + ![Confirm in metamask](/img/iota-evm/evm/how-tos/ERC721/confirm-in-metamask.png) If you visit your address in the visit the [IOTA EVM Explorer](https://explorer.evm.iota.org), -[ShimmerEVM Explorer](https://explorer.evm.testnet.shimmer.network/) or [EVM Testnet Explorer](https://explorer.evm.testnet.shimmer.network/) +[ShimmerEVM Explorer](https://explorer.evm.testnet.shimmer.network/) or [EVM Testnet Explorer](https://explorer.evm.testnet.shimmer.network/) you should see your NFTs listed under `Tokens`. - diff --git a/docs/content/developer/iota-evm/how-tos/core-contracts/basics/send-assets-to-l1.mdx b/docs/content/developer/iota-evm/how-tos/core-contracts/basics/send-assets-to-l1.mdx index bf842e41a6d..8d828f15397 100644 --- a/docs/content/developer/iota-evm/how-tos/core-contracts/basics/send-assets-to-l1.mdx +++ b/docs/content/developer/iota-evm/how-tos/core-contracts/basics/send-assets-to-l1.mdx @@ -2,19 +2,19 @@ description: The ISC Magic Contract allows EVM contracts to access ISC functionality. image: /img/logo/WASP_logo_dark.png tags: - - configure - - using - - EVM - - magic - - Ethereum - - Solidity + - configure + - using + - EVM + - magic + - Ethereum + - Solidity --- -import AboutAccounts from '../../../../../../_snippets/iota-evm/about-accounts.md'; +import AboutAccounts from '../../../../../_snippets/iota-evm/about-accounts.md'; # Send Assets and Tokens to L1 - + :::info @@ -67,4 +67,4 @@ contract L1Assets { ISC.sandbox.send(to, allowance, false, metadata, options); } } -``` \ No newline at end of file +``` diff --git a/docs/content/developer/iota-evm/how-tos/core-contracts/call-view.md b/docs/content/developer/iota-evm/how-tos/core-contracts/call-view.md index 716418cbbc4..b1343c20284 100644 --- a/docs/content/developer/iota-evm/how-tos/core-contracts/call-view.md +++ b/docs/content/developer/iota-evm/how-tos/core-contracts/call-view.md @@ -2,19 +2,19 @@ description: With call and callView you can interact with any core contract image: /img/logo/WASP_logo_dark.png tags: - - magic contract - - core - - EVM - - Ethereum - - Solidity - - ISC + - magic contract + - core + - EVM + - Ethereum + - Solidity + - ISC --- # Interact with any Core contract ## About `call` and `callView` -The magic contract provides you with a solidity interface to the core contracts. Some functions like [`getL2BalanceBaseTokens`](../../../../../references/iota-evm/magic-contract/ISCAccounts.md#getl2balancebasetokens) are wrapped in the magic contract directly, others you need to call yourself. You can do that with the [`call`](../../../../../references/iota-evm/magic-contract/ISCSandbox.md#call) and [`callView`](../../../../../references/iota-evm/magic-contract/ISCSandbox.md#callview) functions. +The magic contract provides you with a solidity interface to the core contracts. Some functions like [`getL2BalanceBaseTokens`](../../../../references/iota-evm/magic-contract/ISCAccounts.md#getl2balancebasetokens) are wrapped in the magic contract directly, others you need to call yourself. You can do that with the [`call`](../../../../references/iota-evm/magic-contract/ISCSandbox.md#call) and [`callView`](../../../../references/iota-evm/magic-contract/ISCSandbox.md#callview) functions. :::info WASM @@ -30,7 +30,7 @@ You can also use `call` and `callView` to interact with WASM contracts. ISCAgentID memory agentID = ISC.sandbox.getSenderAccount(); ``` -2. Initialize the parameters for the call by creating a new [`ISCDict`](../../../../../references/iota-evm/magic-contract/ISCTypes.md#iscdict). As you can see in the docs, [`getl2balancenativetokens`](../../../../../references/iota-evm/magic-contract/ISCAccounts.md#getl2balancenativetokens) takes two parameters.: the Agent ID and the native token ID. So, you have to create a dictionary with two key-value pairs. The key of the first pair (Agent ID) has to be `a` and the key for the second pair (native token ID) `N`. +2. Initialize the parameters for the call by creating a new [`ISCDict`](../../../../references/iota-evm/magic-contract/ISCTypes.md#iscdict). As you can see in the docs, [`getl2balancenativetokens`](../../../../references/iota-evm/magic-contract/ISCAccounts.md#getl2balancenativetokens) takes two parameters.: the Agent ID and the native token ID. So, you have to create a dictionary with two key-value pairs. The key of the first pair (Agent ID) has to be `a` and the key for the second pair (native token ID) `N`. ```solidity ISCDict memory params = ISCDict(new ISCDictItem[](2)); @@ -38,7 +38,7 @@ params.items[0] = ISCDictItem("a", agentID.data); params.items[1] = ISCDictItem("N", nativeTokenID); ``` -3. Now, you can use [`callView`](../../../../../references/iota-evm/magic-contract/ISCSandbox.md#callview) to call our contract. The first parameter is the core contract `hname`, which we can get with the helper utility [`hn`](../../../../../references/iota-evm/magic-contract/ISCUtil.md#hn), and the second parameter is the function we want to call. The last parameter is the dictionary with all function parameters. +3. Now, you can use [`callView`](../../../../references/iota-evm/magic-contract/ISCSandbox.md#callview) to call our contract. The first parameter is the core contract `hname`, which we can get with the helper utility [`hn`](../../../../references/iota-evm/magic-contract/ISCUtil.md#hn), and the second parameter is the function we want to call. The last parameter is the dictionary with all function parameters. ```solidity ISCDict memory result = ISC.sandbox.callView( @@ -60,7 +60,7 @@ Keep in mind that the call and callView functions will always return a dictionar ::: -### Full Example Code +### Full Example Code ```solidity // SPDX-License-Identifier: MIT diff --git a/docs/content/developer/iota-evm/how-tos/core-contracts/introduction.md b/docs/content/developer/iota-evm/how-tos/core-contracts/introduction.md index 7efa57b33fc..5b334cf62c6 100644 --- a/docs/content/developer/iota-evm/how-tos/core-contracts/introduction.md +++ b/docs/content/developer/iota-evm/how-tos/core-contracts/introduction.md @@ -2,27 +2,27 @@ description: The ISC Core Contracts allows VMs to access ISC functionality. image: /img/logo/WASP_logo_dark.png tags: - - configure - - using - - EVM - - magic - - Ethereum - - Solidity - - metamask - - JSON - - RPC + - configure + - using + - EVM + - magic + - Ethereum + - Solidity + - metamask + - JSON + - RPC --- # The Core Contracts -The [core contracts](../../explanations/core-contracts.md) are contracts deployed on every chain and are vital to interact with L1 and the chain itself. They can be called in Solidity through the [ISC Magic Contract](../../../../../references/iota-evm/magic-contract/introduction.md). +The [core contracts](../../explanations/core-contracts.md) are contracts deployed on every chain and are vital to interact with L1 and the chain itself. They can be called in Solidity through the [ISC Magic Contract](../../../../references/iota-evm/magic-contract/introduction.md). ## The ISC Magic Contract The Magic contract is an EVM contract deployed by default on every ISC chain, in the EVM genesis block, at address `0x1074000000000000000000000000000000000000`. The implementation of the Magic contract is baked-in in -the [`evm`](../../../../../references/iota-evm/core-contracts/evm.md) [core contract](../../../../../references/iota-evm/core-contracts/overview.md); +the [`evm`](../../../../references/iota-evm/core-contracts/evm.md) [core contract](../../../../references/iota-evm/core-contracts/overview.md); i.e. it is not a pure-Solidity contract. The Magic contract has several methods, which are categorized into specialized @@ -45,7 +45,7 @@ tokens and native tokens on L2. :::info Reference Docs -If you need further info about magic contracts interfaces you can check out the [magic contract docs](../../../../../references/iota-evm/magic-contract/introduction.md). +If you need further info about magic contracts interfaces you can check out the [magic contract docs](../../../../references/iota-evm/magic-contract/introduction.md). ::: @@ -53,7 +53,7 @@ If you need further info about magic contracts interfaces you can check out the :::info Ease of use -To make it easier for developers to use the core contracts, you should, in most cases, run the functions from the magic contract directly. For example, to get the native token balance, you could [call the `balanceNativeToken()`](./call-view.md) directly with `callView`, or use [`getl2balancenativetokens`](./basics/get-balance.md) of the magic contract, or (the suggested way) register your native token as [`ERC20`](../../../../../references/iota-evm/magic-contract/ERC20NativeTokens.md) and call the standard [`balanceof`](../../../../../references/iota-evm/magic-contract/ERC20NativeTokens.md#balanceof) function. What you use also depends on what you optimize for. For example, to save gas, it could be interesting for you to call core contracts from your favorite web3 library directly and compute other things off-chain. +To make it easier for developers to use the core contracts, you should, in most cases, run the functions from the magic contract directly. For example, to get the native token balance, you could [call the `balanceNativeToken()`](./call-view.md) directly with `callView`, or use [`getl2balancenativetokens`](./basics/get-balance.md) of the magic contract, or (the suggested way) register your native token as [`ERC20`](../../../../references/iota-evm/magic-contract/ERC20NativeTokens.md) and call the standard [`balanceof`](../../../../references/iota-evm/magic-contract/ERC20NativeTokens.md#balanceof) function. What you use also depends on what you optimize for. For example, to save gas, it could be interesting for you to call core contracts from your favorite web3 library directly and compute other things off-chain. ::: diff --git a/docs/content/developer/iota-evm/how-tos/core-contracts/nft/mint-nft.mdx b/docs/content/developer/iota-evm/how-tos/core-contracts/nft/mint-nft.mdx index eeee6254b3f..14a9ce812e8 100644 --- a/docs/content/developer/iota-evm/how-tos/core-contracts/nft/mint-nft.mdx +++ b/docs/content/developer/iota-evm/how-tos/core-contracts/nft/mint-nft.mdx @@ -2,20 +2,22 @@ description: How to mint L1 NFT image: /img/logo/WASP_logo_dark.png tags: - - NFT - - EVM - - how-to + - NFT + - EVM + - how-to --- -import ExampleCodeIntro from '../../../../../../_snippets/iota-evm/how-tos/token/example_code_intro.mdx'; + +import ExampleCodeIntro from '../../../../../_snippets/iota-evm/how-tos/token/example_code_intro.mdx'; # Mint an NFT + ## About NFTs The Stardust update allows you to create your own NFTs. You can also use [IRC27](https://github.com/iotaledger/tips/blob/main/tips/TIP-0027/tip-0027.md) for NFTs. This guide will show you how to create an IRC27 L1 NFT using a L2 smart contract. ## Example Code - + 2. Get the senders AgentID: @@ -23,7 +25,7 @@ The Stardust update allows you to create your own NFTs. You can also use [IRC27] ISCAgentID memory agentID = ISC.sandbox.getSenderAccount(); ``` -3. Create an `IRC27Metadata` struct with all the needed data: +3. Create an `IRC27Metadata` struct with all the needed data: ```solidity IRC27NFTMetadata memory metadata = IRC27NFTMetadata({ @@ -35,9 +37,10 @@ IRC27NFTMetadata memory metadata = IRC27NFTMetadata({ }); ``` -4. Create all the data for the core contract call. To do so, you should create a new `ISCDict` with 2 parameters like specified in the reference docs for [`mintNFT`](../../../../../../references/iota-evm/core-contracts/accounts.md#mintnfti-immutabledata-a-agentid-c-collectionid-w-withdrawonmint) -* `I` is the immutable metadata we fill with the IRC27 metadata and -* `a` is the AgendID of the owner of the NFT +4. Create all the data for the core contract call. To do so, you should create a new `ISCDict` with 2 parameters like specified in the reference docs for [`mintNFT`](../../../../../references/iota-evm/core-contracts/accounts.md#mintnfti-immutabledata-a-agentid-c-collectionid-w-withdrawonmint) + +- `I` is the immutable metadata we fill with the IRC27 metadata and +- `a` is the AgendID of the owner of the NFT ```solidity ISCDict memory params = ISCDict(new ISCDictItem[](2)); @@ -51,7 +54,7 @@ The full example below calls the `IRC27NFTMetadataToString` function, which simp ::: -5. Call the magic contract `call` function with all the parameters. You should specify the core contract you want to call, which in this case is the [`account`](../../../../../../references/iota-evm/core-contracts/accounts.md) contract, and the function for [minting an NFT](../../../../../../references/iota-evm/core-contracts/accounts.md#mintnfti-immutabledata-a-agentid-c-collectionid-w-withdrawonmint) +5. Call the magic contract `call` function with all the parameters. You should specify the core contract you want to call, which in this case is the [`account`](../../../../../references/iota-evm/core-contracts/accounts.md) contract, and the function for [minting an NFT](../../../../../references/iota-evm/core-contracts/accounts.md#mintnfti-immutabledata-a-agentid-c-collectionid-w-withdrawonmint) ```solidity ISCDict memory ret = ISC.sandbox.call( @@ -62,7 +65,7 @@ ISCDict memory ret = ISC.sandbox.call( ); ``` -6. The call return value will contain a `mintID` which we can use in, for example, another contract function to get the actual L1 NFT ID once it is created using the [`accounts.NFTIDbyMintID`](../../../../../../references/iota-evm/core-contracts/accounts.md#nftidbymintidd-mintid) function +6. The call return value will contain a `mintID` which we can use in, for example, another contract function to get the actual L1 NFT ID once it is created using the [`accounts.NFTIDbyMintID`](../../../../../references/iota-evm/core-contracts/accounts.md#nftidbymintidd-mintid) function ```solidity function getNFTIDFromMintID(bytes memory mintID) public view returns (bytes memory) { @@ -75,10 +78,10 @@ function getNFTIDFromMintID(bytes memory mintID) public view returns (bytes memo params ); return ret.items[0].value; -} +} ``` -### Full Example Code +### Full Example Code ```solidity // SPDX-License-Identifier: MIT @@ -128,7 +131,7 @@ contract NFTContract { params ); return ret.items[0].value; - } + } function IRC27NFTMetadataToString(IRC27NFTMetadata memory metadata) public diff --git a/docs/content/developer/iota-evm/how-tos/core-contracts/token/create-foundry.mdx b/docs/content/developer/iota-evm/how-tos/core-contracts/token/create-foundry.mdx index 3893ff63d57..6995be75224 100644 --- a/docs/content/developer/iota-evm/how-tos/core-contracts/token/create-foundry.mdx +++ b/docs/content/developer/iota-evm/how-tos/core-contracts/token/create-foundry.mdx @@ -2,26 +2,27 @@ description: How to create a L1 foundry image: /img/logo/WASP_logo_dark.png tags: - - foundry - - EVM - - how-to + - foundry + - EVM + - how-to --- -import ExampleCodeIntro from '../../../../../../_snippets/iota-evm/how-tos/token/example_code_intro.mdx'; -import ObsoleteTokenCreation from '../../../../../../_snippets/iota-evm/how-tos/token/obsolete_token_creation.md'; + +import ExampleCodeIntro from '../../../../../_snippets/iota-evm/how-tos/token/example_code_intro.mdx'; +import ObsoleteTokenCreation from '../../../../../_snippets/iota-evm/how-tos/token/obsolete_token_creation.md'; # Create a Foundry - + ## About Foundries -The Stardust update allows you to create your own native tokens. Native tokens are minted by a [Foundry](https://github.com/iotaledger/tips/blob/main/tips/TIP-0018/tip-0018.md#foundry-output). -The Foundry allows you to specify your native token's maximum supply **once** and change the circulating supply. +The Stardust update allows you to create your own native tokens. Native tokens are minted by a [Foundry](https://github.com/iotaledger/tips/blob/main/tips/TIP-0018/tip-0018.md#foundry-output). +The Foundry allows you to specify your native token's maximum supply **once** and change the circulating supply. This guide will show you how to create an L1 foundry using a L2 smart contract. ## Example Code - + ### 2. Define the Token Scheme @@ -43,7 +44,7 @@ Create the foundry by calling the `ISC.accounts.foundryCreateNew(nativeTokenSche uint32 foundrySN = ISC.accounts.foundryCreateNew(nativeTokenScheme, allowance); ``` -### Full Example Code +### Full Example Code ```solidity // SPDX-License-Identifier: MIT diff --git a/docs/content/developer/iota-evm/how-tos/core-contracts/token/create-native-token.mdx b/docs/content/developer/iota-evm/how-tos/core-contracts/token/create-native-token.mdx index d8c30e9a017..4c68d6bfb44 100644 --- a/docs/content/developer/iota-evm/how-tos/core-contracts/token/create-native-token.mdx +++ b/docs/content/developer/iota-evm/how-tos/core-contracts/token/create-native-token.mdx @@ -2,32 +2,32 @@ description: How to Create a Native Token Foundry. image: /img/logo/WASP_logo_dark.png tags: - - foundry - - EVM - - how-to - - native tokens - - mint - - register + - foundry + - EVM + - how-to + - native tokens + - mint + - register --- -import ExampleCodeIntro from '../../../../../../_snippets/iota-evm/how-tos/token/example_code_intro.mdx'; +import ExampleCodeIntro from '../../../../../_snippets/iota-evm/how-tos/token/example_code_intro.mdx'; # Create a Native Token -This guide will show you how you can efficiently mint new tokens and register them for use as ERC20 tokens with the [`createNativeTokenFoundry`](../../../../../../references/iota-evm/magic-contract/ISCAccounts.md#createnativetokenfoundry) function in one seamless operation. It will create a foundry on L1 and register it as an ERC20 on L2. This method ensures that only the foundry owner can mint tokens, maintaining security and control over the token creation process. +This guide will show you how you can efficiently mint new tokens and register them for use as ERC20 tokens with the [`createNativeTokenFoundry`](../../../../../references/iota-evm/magic-contract/ISCAccounts.md#createnativetokenfoundry) function in one seamless operation. It will create a foundry on L1 and register it as an ERC20 on L2. This method ensures that only the foundry owner can mint tokens, maintaining security and control over the token creation process. ## About Foundries -The Stardust update allows you to create your own native tokens. Native tokens are minted by a [Foundry](https://github.com/iotaledger/tips/blob/main/tips/TIP-0018/tip-0018.md#foundry-output). +The Stardust update allows you to create your own native tokens. Native tokens are minted by a [Foundry](https://github.com/iotaledger/tips/blob/main/tips/TIP-0018/tip-0018.md#foundry-output). The Foundry lets you specify your native token's maximum supply **once** and change the circulating supply. ## Example Code - + ### 2. Define the Token Scheme -Define the [`NativeTokenScheme`](../../../../../../references/iota-evm/magic-contract/ISCTypes.md#nativetokenscheme) by specifying the `maximumSupply`. +Define the [`NativeTokenScheme`](../../../../../references/iota-evm/magic-contract/ISCTypes.md#nativetokenscheme) by specifying the `maximumSupply`. ```solidity NativeTokenScheme memory nativeTokenScheme = NativeTokenScheme({ @@ -37,16 +37,16 @@ NativeTokenScheme memory nativeTokenScheme = NativeTokenScheme({ }); ``` -### 3. Mint and Register Native Token +### 3. Mint and Register Native Token -Minting native tokens and registering them as ERC20 tokens using [`createNativeTokenFoundry`](../../../../../../references/iota-evm/magic-contract/ISCAccounts.md#createnativetokenfoundry) method +Minting native tokens and registering them as ERC20 tokens using [`createNativeTokenFoundry`](../../../../../references/iota-evm/magic-contract/ISCAccounts.md#createnativetokenfoundry) method ```solidity uint32 foundrySN = ISC.accounts.createNativeTokenFoundry( - _tokenName, - _tokenSymbol, - _tokenDecimals, - nativeTokenScheme, + _tokenName, + _tokenSymbol, + _tokenDecimals, + nativeTokenScheme, allowance ); ``` @@ -59,12 +59,12 @@ pragma solidity ^0.8.0; import "@iota/iscmagic/ISC.sol"; contract MyToken { - event MintedToken(uint32 foundrySN); + event MintedToken(uint32 foundrySN); constructor( - string memory _tokenName, - string memory _tokenSymbol, - uint8 _tokenDecimals, + string memory _tokenName, + string memory _tokenSymbol, + uint8 _tokenDecimals, uint256 _maximumSupply, uint64 _storageDeposit ) payable { @@ -79,10 +79,10 @@ contract MyToken { }); uint32 foundrySN = ISC.accounts.createNativeTokenFoundry( - _tokenName, - _tokenSymbol, - _tokenDecimals, - nativeTokenScheme, + _tokenName, + _tokenSymbol, + _tokenDecimals, + nativeTokenScheme, allowance ); emit MintedToken(foundrySN); diff --git a/docs/content/developer/iota-evm/how-tos/core-contracts/token/mint-token.mdx b/docs/content/developer/iota-evm/how-tos/core-contracts/token/mint-token.mdx index 6d6a5f239c7..5ec1215bd42 100644 --- a/docs/content/developer/iota-evm/how-tos/core-contracts/token/mint-token.mdx +++ b/docs/content/developer/iota-evm/how-tos/core-contracts/token/mint-token.mdx @@ -2,13 +2,14 @@ description: How to mint native token on an L1 foundry. image: /img/logo/WASP_logo_dark.png tags: - - foundry - - EVM - - how-to - - native tokens - - mint + - foundry + - EVM + - how-to + - native tokens + - mint --- -import ExampleCodeIntro from '../../../../../../_snippets/iota-evm/how-tos/token/example_code_intro.mdx'; + +import ExampleCodeIntro from '../../../../../_snippets/iota-evm/how-tos/token/example_code_intro.mdx'; # Mint Native Tokens @@ -16,12 +17,12 @@ To mint tokens from a [foundry](https://github.com/iotaledger/tips/blob/main/tip ## Example Code - + ### 2. Mint the Native Token Mint the native token specifying the foundry serial number, the amount to mint and the allowance. - + ```solidity ISC.accounts.mintNativeTokens(_foundrySN, _amount, allowance); ``` diff --git a/docs/content/developer/iota-evm/how-tos/core-contracts/token/register-token.mdx b/docs/content/developer/iota-evm/how-tos/core-contracts/token/register-token.mdx index 557e6c451b9..cc74183967d 100644 --- a/docs/content/developer/iota-evm/how-tos/core-contracts/token/register-token.mdx +++ b/docs/content/developer/iota-evm/how-tos/core-contracts/token/register-token.mdx @@ -2,37 +2,39 @@ description: How to register a native token as ERC20 image: /img/logo/WASP_logo_dark.png tags: - - ERC20 - - EVM - - how-to + - ERC20 + - EVM + - how-to --- -import ExampleCodeIntro from '../../../../../../_snippets/iota-evm/how-tos/token/example_code_intro.mdx'; -import ObsoleteTokenCreation from '../../../../../../_snippets/iota-evm/how-tos/token/obsolete_token_creation.md'; + +import ExampleCodeIntro from '../../../../../_snippets/iota-evm/how-tos/token/example_code_intro.mdx'; +import ObsoleteTokenCreation from '../../../../../_snippets/iota-evm/how-tos/token/obsolete_token_creation.md'; # Register Tokens - + To properly use your native tokens, you should register them as ERC20 using the `registerERC20NativeToken` function from the ISC magic contract. ## Example Code - - + -### 2. Register the Native Tokens +### 2. Register the Native Tokens Register the native tokens specifying: -* the foundry serial number -* a name -* a symbol -* it's decimals -* the allowance. + +- the foundry serial number +- a name +- a symbol +- it's decimals +- the allowance. + ```solidity ISC.sandbox.registerERC20NativeToken(_foundrySN, _name, _symbol, _decimals, allowance); ``` -### 3. Get the Contract's Address +### 3. Get the Contract's Address Get the ERC20 contract address with `erc20NativeTokensAddress`: diff --git a/docs/content/developer/iota-evm/how-tos/create-a-basic-contract.mdx b/docs/content/developer/iota-evm/how-tos/create-a-basic-contract.mdx index 3056080fe4a..4e575a9e060 100644 --- a/docs/content/developer/iota-evm/how-tos/create-a-basic-contract.mdx +++ b/docs/content/developer/iota-evm/how-tos/create-a-basic-contract.mdx @@ -2,11 +2,12 @@ description: Basic smart contract example. image: /img/logo/WASP_logo_dark.png tags: - - smart contracts - - how to - - basic contract + - smart contracts + - how to + - basic contract --- -import DeployAdmonition from '../../../../_snippets/iota-evm/deploy_a_smart_contract.md'; + +import DeployAdmonition from '../../../_snippets/iota-evm/deploy_a_smart_contract.md'; # Basic Smart Contract Example @@ -44,10 +45,10 @@ contract Counter { This contract simply updates a `count` variable. It has three [entry points](../explanations/smart-contract-anatomy.md#entry-points): -* `increment` and `decrement`: Two full entry points that can alter - the [state](../explanations/smart-contract-anatomy.md#state), i.e. the `count variable`. -* `getCount`: A view only entry point, which simply renders the current `count` state. +- `increment` and `decrement`: Two full entry points that can alter + the [state](../explanations/smart-contract-anatomy.md#state), i.e. the `count variable`. +- `getCount`: A view only entry point, which simply renders the current `count` state. For more information, please visit the [official Solidity documentation](https://docs.soliditylang.org/). - \ No newline at end of file + diff --git a/docs/content/developer/iota-evm/how-tos/deploy-a-smart-contract.mdx b/docs/content/developer/iota-evm/how-tos/deploy-a-smart-contract.mdx index 9fdda126788..7a71a47391c 100644 --- a/docs/content/developer/iota-evm/how-tos/deploy-a-smart-contract.mdx +++ b/docs/content/developer/iota-evm/how-tos/deploy-a-smart-contract.mdx @@ -1,17 +1,18 @@ --- tags: -- Smart Contract Deployment -- Shimmer EVM -- IOTA EVM -- Remix IDE -- Hardhat -- EVM Testnet + - Smart Contract Deployment + - Shimmer EVM + - IOTA EVM + - Remix IDE + - Hardhat + - EVM Testnet image: /img/logo/WASP_logo_dark.png description: 'Learn how to deploy smart contracts to IOTA EVM, Shimmer EVM and EVM Testnet using popular tools like Remix and Hardhat.' --- -import {AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; -import HardhatConfig from '../../../../_snippets/iota-evm/hardhat_config.mdx'; -import MetamaskButtons from '../../../../_snippets/iota-evm/metamask_buttons.mdx'; + +import { AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; +import HardhatConfig from '../../../_snippets/iota-evm/hardhat_config.mdx'; +import MetamaskButtons from '../../../_snippets/iota-evm/metamask_buttons.mdx'; import { Networks } from '@theme/constant'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; @@ -45,7 +46,7 @@ You can check the connection details in the Networks & Endpoints section. ::: - + ### 2. Access Remix IDE @@ -70,8 +71,8 @@ Open your web browser and navigate to [Remix IDE](https://remix.ethereum.org/). 1. Switch to the "Deploy & Run Transactions" tab on the left sidebar. 2. In the "Environment" dropdown, select and select `Injected Web3` from the `Environment` dropdown. - ![Select Injected Provider from the Environment dropdown](/img/iota-evm/evm/remix-injected-provider-metamask.png) - + ![Select Injected Provider from the Environment dropdown](/img/iota-evm/evm/remix-injected-provider-metamask.png) + 3. After selecting the environment, make sure the contract Counter is selected in the `Contract` dropdown. 4. Click the `Deploy` button. If you're using an Ethereum network, confirm the transaction in your Web3 wallet. @@ -89,36 +90,37 @@ project. Here's a step-by-step guide: ### Requirements -* [Node.js](https://nodejs.org/). -* [npm](https://www.npmjs.com/) or [yarn](https://yarnpkg.com/). +- [Node.js](https://nodejs.org/). +- [npm](https://www.npmjs.com/) or [yarn](https://yarnpkg.com/). ### 1. Set Up Hardhat 1. Open a new terminal window. 2. Create a new directory for your project, and navigate into it. For example: - ```bash - mkdir deploy-a-basic-contract && - cd deploy-a-basic-contract - ``` + ```bash + mkdir deploy-a-basic-contract && + cd deploy-a-basic-contract + ``` 3. Create a new node project by running: - ```bash - npm init -y - ``` + ```bash + npm init -y + ``` 4. Install Hardhat by running: - ```bash - npm install --save-dev hardhat - ``` + ```bash + npm install --save-dev hardhat + ``` 5. Create a Hardhat Project by running the following command: - ```bash - npx hardhat init - ``` - Select `Create a JavaScript project` (or whatever applies to your project) when prompted and answer the setup questions (you can press enter to - accept defaults). + ```bash + npx hardhat init + ``` + + Select `Create a JavaScript project` (or whatever applies to your project) when prompted and answer the setup questions (you can press enter to + accept defaults). ### 2. Add Your Contract -1. Inside the `contracts` folder, create a new file called `Counter.sol` and paste the content of +1. Inside the `contracts` folder, create a new file called `Counter.sol` and paste the content of the [Counter Basic Contract](create-a-basic-contract.mdx. ### 3. Create a Deployment Script @@ -126,27 +128,27 @@ project. Here's a step-by-step guide: 1. Navigate to the `scripts` folder. 2. Create a new file called `deploy.js` with the following code: - ```javascript - async function main() { - const Counter = await ethers.getContractFactory("Counter"); - const counter = await Counter.deploy(); - - console.log("Counter deployed to:", await counter.getAddress()); - } - - main() - .then(() => process.exit(0)) - .catch((error) => { - console.error(error); - process.exit(1); - }); - ``` + ```javascript + async function main() { + const Counter = await ethers.getContractFactory('Counter'); + const counter = await Counter.deploy(); + + console.log('Counter deployed to:', await counter.getAddress()); + } + + main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); + ``` ### 4. Compile and Deploy Your Contract 1. Add your preferred network parameters to the `hardhat.config.js`, for example: - + :::info Export the Metamask Private Key @@ -155,7 +157,7 @@ project. Here's a step-by-step guide: 3. On the account page, click the menu (three dots) in the upper right corner, then click the "Account Details" button. 4. Click on "Export Private Key". 5. Enter your wallet password to access your private key and click `Confirm` to continue. -6. Your private key will now be displayed. Click to copy it and save it in a safe place. +6. Your private key will now be displayed. Click to copy it and save it in a safe place. You can find more information in the [official Metamask Documentation](https://support.metamask.io/managing-my-wallet/secret-recovery-phrase-and-private-keys/how-to-export-an-accounts-private-key/). @@ -170,22 +172,23 @@ often offered through block explorer APIs. 2. Compile your contract by running the following command: - ```bash - npx hardhat compile - ``` + ```bash + npx hardhat compile + ``` 3. If you have no compilation errors, you can deploy your contract by running the following command: - ```bash - npx hardhat run scripts/deploy.js --network evm-testnet - ``` + ```bash + npx hardhat run scripts/deploy.js --network evm-testnet + ``` + + **Expected output**: - **Expected output**: + ```bash + Counter deployed to: 0x123456789ABCDEFGHIJK123456789ABCDEFGHIJK + ``` - ```bash - Counter deployed to: 0x123456789ABCDEFGHIJK123456789ABCDEFGHIJK - ``` - ***** `0x123456789ABCDEFGHIJK123456789ABCDEFGHIJK` is the contract unlock address. + **\*** `0x123456789ABCDEFGHIJK123456789ABCDEFGHIJK` is the contract unlock address. 4. You can verify your contract by visiting the [EVM Testnet Explorer](https://explorer.evm.testnet.shimmer.network/), @@ -193,4 +196,4 @@ often offered through block explorer APIs. your code and interact with your contract. - \ No newline at end of file + diff --git a/docs/content/developer/iota-evm/how-tos/send-funds-from-L1-to-L2.mdx b/docs/content/developer/iota-evm/how-tos/send-funds-from-L1-to-L2.mdx index 44222d8c130..71a99849d94 100644 --- a/docs/content/developer/iota-evm/how-tos/send-funds-from-L1-to-L2.mdx +++ b/docs/content/developer/iota-evm/how-tos/send-funds-from-L1-to-L2.mdx @@ -2,22 +2,23 @@ description: How to send funds from L1 to L2. image: /img/logo/WASP_logo_dark.png tags: - - configure - - using - - EVM - - Ethereum - - Solidity - - deploy - - hardhat - - metamask - - JSON - - RPC - - how to + - configure + - using + - EVM + - Ethereum + - Solidity + - deploy + - hardhat + - metamask + - JSON + - RPC + - how to --- + import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -import {AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; -import MetamaskButtons from '../../../../_snippets/iota-evm/metamask_buttons.mdx'; +import { AddToMetaMaskButton } from '@theme/AddToMetaMaskButton'; +import MetamaskButtons from '../../../_snippets/iota-evm/metamask_buttons.mdx'; import { Networks } from '@theme/constant'; # Send Funds From L1 to L2 @@ -43,34 +44,33 @@ You can use your [Firefly Wallet](https://firefly.iota.org/) to easily send L1 I #### Requirements -* IOTA Tokens or Shimmer Tokens -* [Firefly Wallet](https://firefly.iota.org/) -* [Metamask](https://metamask.io/) +- IOTA Tokens or Shimmer Tokens +- [Firefly Wallet](https://firefly.iota.org/) +- [Metamask](https://metamask.io/) 1. The first thing you will need to do is add the EVM to Metamask by hitting the following button. - + 2. Once you have added the EVM to Metamask, you can get your address: - ![Copy your Metamask address](/img/iota-evm/evm/how-tos/get-funds/copy-your-address.png) + ![Copy your Metamask address](/img/iota-evm/evm/how-tos/get-funds/copy-your-address.png) 3. Next, you will need to open your [Firefly Wallet](https://firefly.iota.org/) and click on `Send Assets`. - ![Click send assets](/img/iota-evm/evm/how-tos/get-funds/firefly/select-send-assets.png) + ![Click send assets](/img/iota-evm/evm/how-tos/get-funds/firefly/select-send-assets.png) 4. Select the EVM chain you want to use in the network dropdown. - ![Select the EVM network](/img/iota-evm/evm/how-tos/get-funds/firefly/select-shimmer-evm.png) + ![Select the EVM network](/img/iota-evm/evm/how-tos/get-funds/firefly/select-shimmer-evm.png) 5. Enter the amount of tokens you want to transfer, and the Metamask address from step 2, and click on `Next` - ![Enter the amount of tokens and metamask address](/img/iota-evm/evm/how-tos/get-funds/firefly/enter-your-desired-amount-and-metamask-address.png) - -6. Review the transaction details and click on `Send`. + ![Enter the amount of tokens and metamask address](/img/iota-evm/evm/how-tos/get-funds/firefly/enter-your-desired-amount-and-metamask-address.png) - ![Hit Send](/img/iota-evm/evm/how-tos/get-funds/firefly/hit-send.png) +6. Review the transaction details and click on `Send`. + ![Hit Send](/img/iota-evm/evm/how-tos/get-funds/firefly/hit-send.png) @@ -79,24 +79,24 @@ You can use your [Bloom Wallet](https://bloomwallet.io/) to easily send L1 base 1. First, you will need to open your [Bloom Wallet](https://firefly.iota.org/) and click on `Send`. - ![Click send](/img/iota-evm/evm/how-tos/get-funds/bloom/select-send.png) + ![Click send](/img/iota-evm/evm/how-tos/get-funds/bloom/select-send.png) 2. Select an account with base tokens. - ![Select an account with base tokens](/img/iota-evm/evm/how-tos/get-funds/bloom/select-the-smr-token.png) + ![Select an account with base tokens](/img/iota-evm/evm/how-tos/get-funds/bloom/select-the-smr-token.png) -3. Bloom will automatically create an EVM address for you, so you can send funds to that address from the -EVM dropdown. Alternatively, you can input any other EVM address. +3. Bloom will automatically create an EVM address for you, so you can send funds to that address from the + EVM dropdown. Alternatively, you can input any other EVM address. - ![Select you EVM Address](/img/iota-evm/evm/how-tos/get-funds/bloom/enter-the-recipient-address.png) + ![Select you EVM Address](/img/iota-evm/evm/how-tos/get-funds/bloom/enter-the-recipient-address.png) 4. Enter the amount of base tokens you want to transfer. - - ![Enter the amount of base tokens you want to transfer](/img/iota-evm/evm/how-tos/get-funds/bloom/enter-the-amount.png) + + ![Enter the amount of base tokens you want to transfer](/img/iota-evm/evm/how-tos/get-funds/bloom/enter-the-amount.png) 5. Review the transaction details and click on `Confirm`. - ![Hit Send](/img/iota-evm/evm/how-tos/get-funds/bloom/review-and-confirm-the-transaction.png) + ![Hit Send](/img/iota-evm/evm/how-tos/get-funds/bloom/review-and-confirm-the-transaction.png) - \ No newline at end of file + diff --git a/docs/content/developer/iota-evm/introduction.mdx b/docs/content/developer/iota-evm/introduction.mdx index 02b79068165..3f4d67ceaa7 100644 --- a/docs/content/developer/iota-evm/introduction.mdx +++ b/docs/content/developer/iota-evm/introduction.mdx @@ -11,7 +11,8 @@ tags: - explanation --- -import OnOffLedgerRequest from '../../../_snippets/iota-evm/on_off_ledger_request.md'; + +import OnOffLedgerRequest from '../../_snippets/iota-evm/on_off_ledger_request.md'; # Introduction @@ -23,7 +24,7 @@ Their deterministic and distributed nature makes them predictable, stable and tr Due to the distributed nature of smart contracts, i.e. they run on a network of validators instead of a single computer, the execution of smart contract is resource intensive as it has to deal with the overhead of the communication between validators in the network. -This can lead to relatively high [fees](#gas) for smart contract execution, as well as scalability issues when running on +This can lead to relatively high [fees](#gas) for smart contract execution, as well as scalability issues when running on a single blockchain. However, the IOTA Smart Contract Protocol allows **many blockchains that execute smart contracts to run in parallel** and communicate with one another, therefore solving the scalability problem. Enabling interoperability and horizontal scaling of dApps. @@ -51,8 +52,8 @@ smart contracts, as well as an **experimental** [Wasm VM](getting-started/langua ## Sandbox Interface -ISC Smart contracts can access the [Sandbox interface](explanations/sandbox.md). -This interface provides access to the chain state, native assets, allows interaction with other contracts/chains, as +ISC Smart contracts can access the [Sandbox interface](explanations/sandbox.md). +This interface provides access to the chain state, native assets, allows interaction with other contracts/chains, as well as various utilities like cryptographic functions and event dispatching. ![Sandbox](/img/iota-evm/sandbox.png) @@ -68,7 +69,7 @@ may involve delays. ### Gas -Running a request consumes 'gas'. Gas units are a measurement of "how expensive" a computation is to execute. You can specify a `GasBudget` -for each request, with costs charged to your on-chain account. +Running a request consumes 'gas'. Gas units are a measurement of "how expensive" a computation is to execute. You can specify a `GasBudget` +for each request, with costs charged to your on-chain account. - + diff --git a/docs/content/developer/iota-evm/schema/how-tos/state.mdx b/docs/content/developer/iota-evm/schema/how-tos/state.mdx index e70bb5de702..102870afb10 100644 --- a/docs/content/developer/iota-evm/schema/how-tos/state.mdx +++ b/docs/content/developer/iota-evm/schema/how-tos/state.mdx @@ -1,11 +1,11 @@ --- tags: - - state - - access - - storage - - key - - data - - value + - state + - access + - storage + - key + - data + - value description: The smart contract state storage on the host consists of a single key/value map, as long as you access the data in the same way that you used to store it, you will always get valid data back. @@ -39,13 +39,13 @@ Take a closer look at the `state` section in the `dividend` example to understan ```yaml state: - memberList: Address[] # array with all the recipients of this dividend + memberList: Address[] # array with all the recipients of this dividend - # factors per member + # factors per member - members: map[Address]Uint64 # map with all the recipient factors of this dividend - owner: AgentID # owner of contract, the only one who can call 'member' func - totalFactor: Uint64 # sum of all recipient factors + members: map[Address]Uint64 # map with all the recipient factors of this dividend + owner: AgentID # owner of contract, the only one who can call 'member' func + totalFactor: Uint64 # sum of all recipient factors ``` @@ -55,7 +55,7 @@ state: Starting with straightforward state variables, `totalFactor`, and `owner` are characterized as Uint64 and AgentID, respectively. -These represent predefined [WasmLib value types](../../../../../references/iota-evm/wasm-lib-data-types.mdx). +These represent predefined [WasmLib value types](../../../../references/iota-evm/wasm-lib-data-types.mdx). ### Arrays and Maps @@ -140,29 +140,29 @@ impl MutableDividendState { ```ts export class MutableDividendState extends wasmtypes.ScProxy { - asImmutable(): sc.ImmutableDividendState { - return new sc.ImmutableDividendState(this.proxy); - } - - // array with all the recipients of this dividend - memberList(): sc.ArrayOfMutableAddress { - return new sc.ArrayOfMutableAddress(this.proxy.root(sc.StateMemberList)); - } - - // map with all the recipient factors of this dividend - members(): sc.MapAddressToMutableUint64 { - return new sc.MapAddressToMutableUint64(this.proxy.root(sc.StateMembers)); - } - - // owner of contract, the only one who can call 'member' func - owner(): wasmtypes.ScMutableAgentID { - return new wasmtypes.ScMutableAgentID(this.proxy.root(sc.StateOwner)); - } - - // sum of all recipient factors - totalFactor(): wasmtypes.ScMutableUint64 { - return new wasmtypes.ScMutableUint64(this.proxy.root(sc.StateTotalFactor)); - } + asImmutable(): sc.ImmutableDividendState { + return new sc.ImmutableDividendState(this.proxy); + } + + // array with all the recipients of this dividend + memberList(): sc.ArrayOfMutableAddress { + return new sc.ArrayOfMutableAddress(this.proxy.root(sc.StateMemberList)); + } + + // map with all the recipient factors of this dividend + members(): sc.MapAddressToMutableUint64 { + return new sc.MapAddressToMutableUint64(this.proxy.root(sc.StateMembers)); + } + + // owner of contract, the only one who can call 'member' func + owner(): wasmtypes.ScMutableAgentID { + return new wasmtypes.ScMutableAgentID(this.proxy.root(sc.StateOwner)); + } + + // sum of all recipient factors + totalFactor(): wasmtypes.ScMutableUint64 { + return new wasmtypes.ScMutableUint64(this.proxy.root(sc.StateTotalFactor)); + } } ``` diff --git a/docs/content/developer/iota-evm/schema/how-tos/typedefs.mdx b/docs/content/developer/iota-evm/schema/how-tos/typedefs.mdx index 0447b2b4f7b..195ce73d054 100644 --- a/docs/content/developer/iota-evm/schema/how-tos/typedefs.mdx +++ b/docs/content/developer/iota-evm/schema/how-tos/typedefs.mdx @@ -1,11 +1,11 @@ --- tags: - - containers - - types - - container types - - single type - - array - - schema definition file + - containers + - types + - container types + - single type + - array + - schema definition file description: You can add a typedefs section to the schema definition file, where you can define a single type name for a container type. This way you can easily create containers that contain container types. @@ -19,7 +19,7 @@ import TabItem from '@theme/TabItem'; :::note WasmLib Types -You can find the complete list of [WasmLib Data Types](../../../../../references/iota-evm/wasm-lib-data-types.mdx) in the reference section. +You can find the complete list of [WasmLib Data Types](../../../../references/iota-evm/wasm-lib-data-types.mdx) in the reference section. ::: @@ -44,9 +44,9 @@ Instead, now you add the following to your schema definition file: ```yaml typedefs: - BettingRound: Bet[] // one round of bets + BettingRound: Bet[] // one round of bets state: - rounds: BettingRound[] // keep track of all betting rounds + rounds: BettingRound[] // keep track of all betting rounds ``` @@ -159,33 +159,33 @@ import * as wasmtypes from 'wasmlib/wasmtypes'; import * as sc from './index'; export class ArrayOfImmutableBet extends wasmtypes.ScProxy { - length(): u32 { - return this.proxy.length(); - } + length(): u32 { + return this.proxy.length(); + } - getBet(index: u32): sc.ImmutableBet { - return new sc.ImmutableBet(this.proxy.index(index)); - } + getBet(index: u32): sc.ImmutableBet { + return new sc.ImmutableBet(this.proxy.index(index)); + } } export class ImmutableBettingRound extends ArrayOfImmutableBet {} export class ArrayOfMutableBet extends wasmtypes.ScProxy { - appendBet(): sc.MutableBet { - return new sc.MutableBet(this.proxy.append()); - } + appendBet(): sc.MutableBet { + return new sc.MutableBet(this.proxy.append()); + } - clear(): void { - this.proxy.clearArray(); - } + clear(): void { + this.proxy.clearArray(); + } - length(): u32 { - return this.proxy.length(); - } + length(): u32 { + return this.proxy.length(); + } - getBet(index: u32): sc.MutableBet { - return new sc.MutableBet(this.proxy.index(index)); - } + getBet(index: u32): sc.MutableBet { + return new sc.MutableBet(this.proxy.index(index)); + } } export class MutableBettingRound extends ArrayOfMutableBet {} @@ -383,67 +383,67 @@ import * as wasmtypes from 'wasmlib/wasmtypes'; import * as sc from './index'; export class ArrayOfImmutableBettingRound extends wasmtypes.ScProxy { - length(): u32 { - return this.proxy.length(); - } + length(): u32 { + return this.proxy.length(); + } - getBettingRound(index: u32): sc.ImmutableBettingRound { - return new sc.ImmutableBettingRound(this.proxy.index(index)); - } + getBettingRound(index: u32): sc.ImmutableBettingRound { + return new sc.ImmutableBettingRound(this.proxy.index(index)); + } } export class ImmutableBettingState extends wasmtypes.ScProxy { - // all bets that were made in this round - bets(): sc.ArrayOfImmutableBet { - return new sc.ArrayOfImmutableBet(this.proxy.root(sc.StateBets)); - } + // all bets that were made in this round + bets(): sc.ArrayOfImmutableBet { + return new sc.ArrayOfImmutableBet(this.proxy.root(sc.StateBets)); + } - // current owner of this smart contract - owner(): wasmtypes.ScImmutableAgentID { - return new wasmtypes.ScImmutableAgentID(this.proxy.root(sc.StateOwner)); - } + // current owner of this smart contract + owner(): wasmtypes.ScImmutableAgentID { + return new wasmtypes.ScImmutableAgentID(this.proxy.root(sc.StateOwner)); + } - rounds(): sc.ArrayOfImmutableBettingRound { - return new sc.ArrayOfImmutableBettingRound(this.proxy.root(sc.StateRounds)); - } + rounds(): sc.ArrayOfImmutableBettingRound { + return new sc.ArrayOfImmutableBettingRound(this.proxy.root(sc.StateRounds)); + } } export class ArrayOfMutableBettingRound extends wasmtypes.ScProxy { - appendBettingRound(): sc.MutableBettingRound { - return new sc.MutableBettingRound(this.proxy.append()); - } + appendBettingRound(): sc.MutableBettingRound { + return new sc.MutableBettingRound(this.proxy.append()); + } - clear(): void { - this.proxy.clearArray(); - } + clear(): void { + this.proxy.clearArray(); + } - length(): u32 { - return this.proxy.length(); - } + length(): u32 { + return this.proxy.length(); + } - getBettingRound(index: u32): sc.MutableBettingRound { - return new sc.MutableBettingRound(this.proxy.index(index)); - } + getBettingRound(index: u32): sc.MutableBettingRound { + return new sc.MutableBettingRound(this.proxy.index(index)); + } } export class MutableBettingState extends wasmtypes.ScProxy { - asImmutable(): sc.ImmutableBettingState { - return new sc.ImmutableBettingState(this.proxy); - } - - // all bets that were made in this round - bets(): sc.ArrayOfMutableBet { - return new sc.ArrayOfMutableBet(this.proxy.root(sc.StateBets)); - } - - // current owner of this smart contract - owner(): wasmtypes.ScMutableAgentID { - return new wasmtypes.ScMutableAgentID(this.proxy.root(sc.StateOwner)); - } - - rounds(): sc.ArrayOfMutableBettingRound { - return new sc.ArrayOfMutableBettingRound(this.proxy.root(sc.StateRounds)); - } + asImmutable(): sc.ImmutableBettingState { + return new sc.ImmutableBettingState(this.proxy); + } + + // all bets that were made in this round + bets(): sc.ArrayOfMutableBet { + return new sc.ArrayOfMutableBet(this.proxy.root(sc.StateBets)); + } + + // current owner of this smart contract + owner(): wasmtypes.ScMutableAgentID { + return new wasmtypes.ScMutableAgentID(this.proxy.root(sc.StateOwner)); + } + + rounds(): sc.ArrayOfMutableBettingRound { + return new sc.ArrayOfMutableBettingRound(this.proxy.root(sc.StateRounds)); + } } ``` diff --git a/docs/content/developer/iota-evm/solo/how-tos/error-handling.md b/docs/content/developer/iota-evm/solo/how-tos/error-handling.md index 66605e4bbd4..ae4c00683ee 100644 --- a/docs/content/developer/iota-evm/solo/how-tos/error-handling.md +++ b/docs/content/developer/iota-evm/solo/how-tos/error-handling.md @@ -2,12 +2,12 @@ description: What happens when a smart contract invocation fails? image: /img/logo/WASP_logo_dark.png tags: - - testing - - solo - - error handling - - panic - - state - - transition + - testing + - solo + - error handling + - panic + - state + - transition --- # Error Handling @@ -44,7 +44,7 @@ Note that this test still ends with the state `#4`, although the last request to ``` This shows that a chain block is always generated, regardless of whether the smart contract call succeeds or not. The -result of the request is stored in the chain's [`blocklog`](../../../../../references/iota-evm/core-contracts/blocklog.md) in the form of +result of the request is stored in the chain's [`blocklog`](../../../../references/iota-evm/core-contracts/blocklog.md) in the form of a receipt. In fact, the received Go error `err` in the test above is just generated from the request receipt. If a panic occurs during a smart contract call, it is recovered by the VM context, and the request is marked as failed. diff --git a/docs/content/developer/iota-evm/solo/how-tos/first-example.md b/docs/content/developer/iota-evm/solo/how-tos/first-example.md index e9a93893f4a..44f40e818d3 100644 --- a/docs/content/developer/iota-evm/solo/how-tos/first-example.md +++ b/docs/content/developer/iota-evm/solo/how-tos/first-example.md @@ -2,19 +2,19 @@ description: Example of a _Solo_ test. It deploys a new chain and invokes some view calls. image: /img/logo/WASP_logo_dark.png tags: - - testing framework - - golang - - solo - - example - - new chain - - how-tos + - testing framework + - golang + - solo + - example + - new chain + - how-tos --- # First Example The following is an example of a _Solo_ test. It deploys a new chain and invokes some view calls in the -[`root`](../../../../../references/iota-evm/core-contracts/root.md) and [`governance`](../../../../../references/iota-evm/core-contracts/governance.md) -[core contracts](../../../../../references/iota-evm/core-contracts/overview.md). +[`root`](../../../../references/iota-evm/core-contracts/root.md) and [`governance`](../../../../references/iota-evm/core-contracts/governance.md) +[core contracts](../../../../references/iota-evm/core-contracts/overview.md). ```go import ( @@ -72,16 +72,16 @@ The output of the test will be something like this: :::note -- The example uses [`stretchr/testify`](https://github.com/stretchr/testify) for assertions, but it is not strictly - required. -- Addresses, chain IDs and other hashes should be the same on each run of the test because Solo uses a constant seed by - default. -- The timestamps shown in the log come from the computer's timer, but the Solo environment operates on its own logical - time. +- The example uses [`stretchr/testify`](https://github.com/stretchr/testify) for assertions, but it is not strictly + required. +- Addresses, chain IDs and other hashes should be the same on each run of the test because Solo uses a constant seed by + default. +- The timestamps shown in the log come from the computer's timer, but the Solo environment operates on its own logical + time. ::: -The [core contracts](../../../../../references/iota-evm/core-contracts/overview.md) listed in the log are automatically deployed on each +The [core contracts](../../../../references/iota-evm/core-contracts/overview.md) listed in the log are automatically deployed on each new chain. The log also shows their _contract IDs_. The output fragment in the log `state transition --> #1` means that the state of the chain has changed from block index diff --git a/docs/content/developer/iota-evm/solo/how-tos/test.mdx b/docs/content/developer/iota-evm/solo/how-tos/test.mdx index 07b4b752387..cbf7eb53b59 100644 --- a/docs/content/developer/iota-evm/solo/how-tos/test.mdx +++ b/docs/content/developer/iota-evm/solo/how-tos/test.mdx @@ -1,12 +1,12 @@ --- tags: - - testing - - solo testing environment - - call context - - smart contract functionalities - - data types - - type conversions - - Go + - testing + - solo testing environment + - call context + - smart contract functionalities + - data types + - type conversions + - Go description: Testing of smart contracts happens in the Solo testing environment. This enables synchronous, deterministic testing of smart contract functionality without the overhead of having to start nodes, set up a committee, and send transactions over the _Tangle_. image: /img/logo/WASP_logo_dark.png @@ -26,7 +26,7 @@ combination with Solo to deploy chains and smart contracts and simulate transact Solo directly interacts with the ISC code, and therefore uses all the ISC-specific data types directly. Our Wasm smart contracts cannot access these types directly, because they run in a separate, sandboxed environment. Therefore, WasmLib implements its -[own versions](../../../../../references/iota-evm/wasm-lib-data-types.mdx) of these data types, and the _VM_ layer acts as a data type +[own versions](../../../../references/iota-evm/wasm-lib-data-types.mdx) of these data types, and the _VM_ layer acts as a data type translator between both systems. The impact of this type transformation used to be that to be able to write tests in the diff --git a/docs/content/developer/iota-evm/solo/how-tos/the-l2-ledger.md b/docs/content/developer/iota-evm/solo/how-tos/the-l2-ledger.md index 02f2af5823f..de7727d489b 100644 --- a/docs/content/developer/iota-evm/solo/how-tos/the-l2-ledger.md +++ b/docs/content/developer/iota-evm/solo/how-tos/the-l2-ledger.md @@ -100,10 +100,10 @@ func TestTutorialAccounts(t *testing.T) { The example above creates a chain and a wallet with `utxodb.FundsFromFaucetAmount` base tokens on L1. Then, it sends 1 million tokens to the corresponding on-chain account by posting a -[`deposit`](../../../../../references/iota-evm/core-contracts/accounts.md#deposit) request to the -[`accounts` core contract](../../../../../references/iota-evm/core-contracts/accounts.md) on the chain. +[`deposit`](../../../../references/iota-evm/core-contracts/accounts.md#deposit) request to the +[`accounts` core contract](../../../../references/iota-evm/core-contracts/accounts.md) on the chain. -Finally, it sends a [`withdraw`](../../../../../references/iota-evm/core-contracts/accounts.md#withdraw) request to the `accounts` core +Finally, it sends a [`withdraw`](../../../../references/iota-evm/core-contracts/accounts.md#withdraw) request to the `accounts` core contract to get the tokens back to L1. Both requests are affected by the gas fees and the storage deposit. diff --git a/docs/content/developer/iota-evm/solo/how-tos/view-sc.md b/docs/content/developer/iota-evm/solo/how-tos/view-sc.md index d616ee717c8..9650295b3e0 100644 --- a/docs/content/developer/iota-evm/solo/how-tos/view-sc.md +++ b/docs/content/developer/iota-evm/solo/how-tos/view-sc.md @@ -2,13 +2,13 @@ description: Calling smart contract view functions with Solo. image: /img/iota-evm/tutorial/call_view.png tags: - - how to - - testing - - solo - - views - - call - - synchronous - - entry points + - how to + - testing + - solo + - views + - call + - synchronous + - entry points --- # Calling a View @@ -33,7 +33,7 @@ view entry point will result in an exception, returning all attached tokens to t Views are used to retrieve information about the smart contract's state, for example, to display on a website. Certain Solo methods such as `chain.GetInfo`, `chain.GetGasFeePolicy`, and `chain.L2Assets` call views of -the [core smart contracts](../../../../../references/iota-evm/core-contracts/overview.md) behind the scenes to retrieve the information +the [core smart contracts](../../../../references/iota-evm/core-contracts/overview.md) behind the scenes to retrieve the information about the chain or a specific smart contract. ## Decoding Results Returned by _PostRequestSync_ and _CallView_ diff --git a/docs/content/operator/iota-evm/how-tos/chain-management.md b/docs/content/operator/iota-evm/how-tos/chain-management.md index 4d9fa4a1f91..6395f61ccb3 100644 --- a/docs/content/operator/iota-evm/how-tos/chain-management.md +++ b/docs/content/operator/iota-evm/how-tos/chain-management.md @@ -20,7 +20,7 @@ You can view the chain state using the dashboard (`/wasp/dashboard` when us ## Manage Chain Configuration and Validators You can manage the chain configuration and committee of validators by interacting with -the [Governance contract](/isc/../../../references/iota-evm/core-contracts/governance). +the [Governance contract](/isc/../../references/iota-evm/core-contracts/governance). The “Chain Owner” is the only one who can perform administrative tasks. @@ -33,9 +33,9 @@ the next owner. The next owner must call `claimChainOwnership` to finalize the p For new access nodes to join the network, they need to: -- Be added as a trusted peer to at least 1 of the existing nodes. -- Be added by the administrator to the list of access nodes by calling `changeAccessNodes`. There is a helper in - wasp-cli to do so: +- Be added as a trusted peer to at least 1 of the existing nodes. +- Be added by the administrator to the list of access nodes by calling `changeAccessNodes`. There is a helper in + wasp-cli to do so: ```shell wasp-cli chain gov-change-access-nodes accept @@ -59,9 +59,9 @@ This node won't be "officially" recognized by the committee but will still be ab You can do this in different ways, depending on who controls the [governor address](https://github.com/iotaledger/tips/blob/main/tips/TIP-0018/tip-0018.md#alias-output) from the alias output of the chain. -- If the chain governor address is the chain committee, you can perform the rotation by calling - `rotateStateController` after adding the next state controller via `addAllowedStateControllerAddress`. -- If the chain governor address is a regular user wallet that you control, you can issue the rotation transaction using wasp-cli: +- If the chain governor address is the chain committee, you can perform the rotation by calling + `rotateStateController` after adding the next state controller via `addAllowedStateControllerAddress`. +- If the chain governor address is a regular user wallet that you control, you can issue the rotation transaction using wasp-cli: ```shell wasp-cli chain rotate diff --git a/docs/content/operator/iota-evm/how-tos/setting-up-a-chain.md b/docs/content/operator/iota-evm/how-tos/setting-up-a-chain.md index 0ad532a1b30..5fe80e25e2c 100644 --- a/docs/content/operator/iota-evm/how-tos/setting-up-a-chain.md +++ b/docs/content/operator/iota-evm/how-tos/setting-up-a-chain.md @@ -2,12 +2,12 @@ description: 'Setting up a chain: requirements, configuration parameters, validators, and tests.' image: /img/logo/WASP_logo_dark.png tags: - - Smart Contracts - - Chain - - Set up - - Configuration - - Nodes - - Tests + - Smart Contracts + - Chain + - Set up + - Configuration + - Nodes + - Tests --- # Set Up a Chain @@ -22,7 +22,7 @@ However, in normal operation, multiple Wasp _nodes_ should be used. ## Requirements -- [`wasp-cli` configured](wasp-cli.md) to interact with your wasp node. +- [`wasp-cli` configured](wasp-cli.md) to interact with your wasp node. ## Trust Setup @@ -84,7 +84,7 @@ From now on, all chain commands will target this chain. The `--quorum` flag indicates the minimum number of nodes required to form a _consensus_. The recommended formula to obtain this number is `floor(N*2/3)+1` where `N` is the number of nodes in your committee. -The `--block-keep-amount` parameter determines how many blocks are stored in the [`blocklog`](/isc/../../../references/iota-evm/core-contracts/blocklog) core contract. +The `--block-keep-amount` parameter determines how many blocks are stored in the [`blocklog`](/isc/../../references/iota-evm/core-contracts/blocklog) core contract. After deployment, the chain must be activated by the node operators of all peers. @@ -96,7 +96,7 @@ wasp-cli chain activate --chain= ## Test If It Works You can check that the chain was deployed correctly in the Wasp node dashboard (`/wasp/dashboard` when using `node-docker-setup`). -Note that the chain was deployed with some [core contracts](/isc/../../../references/iota-evm/core-contracts/overview). +Note that the chain was deployed with some [core contracts](/isc/../../references/iota-evm/core-contracts/overview). You should also have an EVM-JSONRPC server opened on: From 72d103b8e62bbec3c8d6586fc2fde6b3565a18e0 Mon Sep 17 00:00:00 2001 From: Jeroen van den Hout Date: Tue, 11 Jun 2024 15:00:43 +0200 Subject: [PATCH 23/37] feat(docs): add Identity docs --- .../developer/iota-identity/contact.mdx | 17 + .../developer/iota-identity/contribute.mdx | 49 + .../explanations/about-alias-outputs.mdx | 64 + .../decentralized-identifiers.mdx | 144 + .../explanations/verifiable-credentials.mdx | 74 + .../explanations/verifiable-presentations.mdx | 39 + .../guides/developer/iota-identity/faq.mdx | 53 + .../iota-identity/getting-started/rust.mdx | 68 + .../iota-identity/getting-started/wasm.mdx | 339 + .../developer/iota-identity/glossary.mdx | 141 + .../decentralized-identifiers/create.mdx | 180 + .../decentralized-identifiers/delete.mdx | 106 + .../decentralized-identifiers/resolve.mdx | 196 + .../decentralized-identifiers/update.mdx | 534 ++ .../domain-linkage/create-and-verify.mdx | 179 + .../iota-identity/how-tos/key-storage.mdx | 152 + .../how-tos/verifiable-credentials/create.mdx | 141 + .../verifiable-credentials/revocation.mdx | 208 + .../selective-disclosure.mdx | 141 + .../zero-knowledge-selective-disclosure.mdx | 151 + .../create-and-validate.mdx | 116 + .../developer/iota-identity/welcome.mdx | 91 + .../developer/iota-identity/workflow.mdx | 179 + docs/content/references/iota-identity/wasm.md | 7684 +++++++++++++++++ docs/content/sidebars/developer.js | 73 + docs/content/sidebars/references.js | 24 + .../iota-identity/iota-did-method-spec.mdx | 263 + .../standards/iota-identity/overview.mdx | 15 + .../iota-identity/revocation-bitmap-2022.mdx | 201 + .../revocation-timeframe-2024.mdx | 150 + 30 files changed, 11772 insertions(+) create mode 100644 docs/content/guides/developer/iota-identity/contact.mdx create mode 100644 docs/content/guides/developer/iota-identity/contribute.mdx create mode 100644 docs/content/guides/developer/iota-identity/explanations/about-alias-outputs.mdx create mode 100644 docs/content/guides/developer/iota-identity/explanations/decentralized-identifiers.mdx create mode 100644 docs/content/guides/developer/iota-identity/explanations/verifiable-credentials.mdx create mode 100644 docs/content/guides/developer/iota-identity/explanations/verifiable-presentations.mdx create mode 100644 docs/content/guides/developer/iota-identity/faq.mdx create mode 100644 docs/content/guides/developer/iota-identity/getting-started/rust.mdx create mode 100644 docs/content/guides/developer/iota-identity/getting-started/wasm.mdx create mode 100644 docs/content/guides/developer/iota-identity/glossary.mdx create mode 100644 docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/create.mdx create mode 100644 docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/delete.mdx create mode 100644 docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/resolve.mdx create mode 100644 docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/update.mdx create mode 100644 docs/content/guides/developer/iota-identity/how-tos/domain-linkage/create-and-verify.mdx create mode 100644 docs/content/guides/developer/iota-identity/how-tos/key-storage.mdx create mode 100644 docs/content/guides/developer/iota-identity/how-tos/verifiable-credentials/create.mdx create mode 100644 docs/content/guides/developer/iota-identity/how-tos/verifiable-credentials/revocation.mdx create mode 100644 docs/content/guides/developer/iota-identity/how-tos/verifiable-credentials/selective-disclosure.mdx create mode 100644 docs/content/guides/developer/iota-identity/how-tos/verifiable-credentials/zero-knowledge-selective-disclosure.mdx create mode 100644 docs/content/guides/developer/iota-identity/how-tos/verifiable-presentations/create-and-validate.mdx create mode 100644 docs/content/guides/developer/iota-identity/welcome.mdx create mode 100644 docs/content/guides/developer/iota-identity/workflow.mdx create mode 100644 docs/content/references/iota-identity/wasm.md create mode 100644 docs/content/standards/iota-identity/iota-did-method-spec.mdx create mode 100644 docs/content/standards/iota-identity/overview.mdx create mode 100644 docs/content/standards/iota-identity/revocation-bitmap-2022.mdx create mode 100644 docs/content/standards/iota-identity/revocation-timeframe-2024.mdx diff --git a/docs/content/guides/developer/iota-identity/contact.mdx b/docs/content/guides/developer/iota-identity/contact.mdx new file mode 100644 index 00000000000..3c2958c5c24 --- /dev/null +++ b/docs/content/guides/developer/iota-identity/contact.mdx @@ -0,0 +1,17 @@ +--- +title: Contact +sidebar_label: Contact +description: Get in touch with the project maintainers. +image: /img/Identity_icon.png +tags: + - Contact + - GitHub + - Maintainers +--- + +If you found a security related issue, please follow the [responsible disclosure policy](https://github.com/iotaledger/identity.rs/security/policy). + +For everything else, you can get in contact with the project by: + +- Creating an [issue](https://github.com/iotaledger/identity.rs/issues/new/choose) on [GitHub](https://github.com/iotaledger/identity.rs). +- Joining the `identity` channel on the [IOTA Discord](https://discord.iota.org/). diff --git a/docs/content/guides/developer/iota-identity/contribute.mdx b/docs/content/guides/developer/iota-identity/contribute.mdx new file mode 100644 index 00000000000..30116554ab5 --- /dev/null +++ b/docs/content/guides/developer/iota-identity/contribute.mdx @@ -0,0 +1,49 @@ +--- +title: Contribute to the project +sidebar_label: Contribute +description: Contribute to IOTA Identity by joining the Identity initiative, via the projects GitHub repository, documentation, or sharing your knowledge. +image: /img/Identity_icon.png +tags: + - Contribute + - GitHub + - Identity Initiative + - Documentation + - Discord + - reference +--- + +**Thanks for thinking about contributing to the project! You can contribute using the following ways.** + +## Join the Identity Initiative + +The [Identity Initiative](https://github.com/iota-community/X-Team_IOTA_Identity) is a collaborative effort to help improve the developer experience that includes: + +- Quality assurance and review. +- Documentation. +- Code samples. + +If you would like to get involved, join the [#x-team-identity](https://discord.com/channels/397872799483428865/773274309861834782) channel on [Discord](https://discord.iota.org). + +## Contribute to the Project's GitHub Repository + +All of the code is open source and hosted on [GitHub](https://github.com/iotaledger/identity.rs) where you can: + +- [Report a bug](https://github.com/iotaledger/identity.rs/issues/new/choose). +- [Suggest a new feature](https://github.com/iotaledger/identity.rs/blob/main/.github/CONTRIBUTING.md). +- [Contribute to the documentation](#contribute-to-the-documentation). + +## Contribute to the Documentation + +This documentation is also open source and hosted on GitHub. + +If you want to contribute new documentation or fix an error, see the [contribution guidelines](https://github.com/iotaledger/iota-wiki/blob/main/.github/CONTRIBUTING.md). + +## Share Your Knowledge + +Helping others is an important part of any open source ecosystem. + +By sharing your knowledge with others, you can provide a lot of value to the community and maybe inspire someone else to learn and contribute. + +Take a look at what discussions are going on in the `#identity-discussion` channel on [Discord](https://discord.iota.org). + +Thanks :heart: diff --git a/docs/content/guides/developer/iota-identity/explanations/about-alias-outputs.mdx b/docs/content/guides/developer/iota-identity/explanations/about-alias-outputs.mdx new file mode 100644 index 00000000000..c7c160a0e41 --- /dev/null +++ b/docs/content/guides/developer/iota-identity/explanations/about-alias-outputs.mdx @@ -0,0 +1,64 @@ +--- +title: Alias Outputs +description: UTXO Alias Ouput +image: /img/Identity_icon.png +tags: + - public keys + - utxo + - Method Specification + - Decentralized Identifiers + - overview + - DLT +--- + +# Alias Outputs + +:::info TL;DR + +The IOTA DID method uses Alias Outputs for storing DID Documents. +Alias Outputs are created via transactions, +and require a [storage deposit](/learn/protocols/stardust/core-concepts/storage-deposit/) to cover the data storage. +The deposit is refundable upon destruction of the output. + +Each Alias Output has an `Alias ID` that becomes the basis for the DID, +and which can be transferred through transactions to update DID Documents. + +::: + + +The IOTA DID method uses the IOTA ledger, which is baed on the unspent transaction output (_UTXO_) model, +as well as the features of the [Stardust](/introduction/stardust/explanations/what_is_stardust) upgrade, +which are fundamental to the IOTA DID method. + +The Alias Output is used to store a DID Document on the ledger. +It is a specific implementation of the UTXO _state machine_ that can hold arbitrary data in its `State Metadata`. +The Alias Output has two kinds of controllers, a state controller and a governor. + +The state controller can only execute state transitions, which update the data in the `State Metadata`. + +The governor, on the contrary, can't update the `State Metadata` but can change controllers and even destroy the Alias Output. + +A controller can be either Ed25519 Address, [Alias Address or an _NFT_ Address](/learn/protocols/stardust/core-concepts/multi-asset-ledger/). Only one of each of these types can be set for an Alias Output. + +To create a new Alias Output, a transaction must be made that includes another Output as input, +a Basic Output, for example, and the new Alias Output as output. + +### Storage Deposit + +The arbitrary data stored in the `State Metadata` of the Alias output must be covered by a +[storage deposit](/learn/protocols/stardust/core-concepts/storage-deposit/). +This helps to control the ledger size from growing uncontrollably while guaranteeing the data +is indefinitely stored on the ledger, which is important for resolving DID Documents. +This deposit is fully refundable and can be reclaimed when the output is destroyed. + +Both the state controller and the governor can control the tokens stored in the Alias Output. +_Nodes_ expose an API to calculate the required deposit depending on the size of the data stored. + +### Alias ID + +Each Alias Output has an `Alias ID`. This ID is assigned after a transaction creates the Alias Output. +The actual DID is derived from this `Alias ID`, so it will be unknown before publishing the transaction. +Consequently, the DID inside the `State Metadata` is replaced by the placeholder `did:0:0` to indicate self. + +If a transaction has an Alias Output as input, its `Alias ID` can be kept by one of its outputs. +This feature is necessary for updating the DID Documents since the DID itself is derived from the `Alias ID`. diff --git a/docs/content/guides/developer/iota-identity/explanations/decentralized-identifiers.mdx b/docs/content/guides/developer/iota-identity/explanations/decentralized-identifiers.mdx new file mode 100644 index 00000000000..f4e21c5e0eb --- /dev/null +++ b/docs/content/guides/developer/iota-identity/explanations/decentralized-identifiers.mdx @@ -0,0 +1,144 @@ +--- +description: The Decentralized Identifiers (DID) standard from W3C is the fundamental standard that supports the concept of a decentralized digital identity. Explore the basic aspects of the DID standard. +image: /img/Identity_icon.png +tags: + - public keys + - Method Specification + - Decentralized Identifiers + - overview + - DLT +--- + +# Decentralized Identifiers (DID) + +:::info TL;DR + +DIDs are unique identifiers that can be resolved to DID Documents containing public keys and URIs for identity verification and public information. + +Adhering to the W3C's DID specifications, IOTA's implementation ensures interoperability and security within its ledger. + +DIDs support self-sovereign identity, allowing identity owners to control their creation and destruction, +while facilitating encrypted communication. + +::: + + +A DID is a unique identifier that can be resolved to a DID Document. This document contains data such as public keys, enabling the holder to prove ownership over their personal data, but also URIs that link to public information about the identity. DIDs are the fundamental building blocks of decentralized digital identity. +This implementation complies with the [DID specifications v1.0](https://www.w3.org/TR/did-core//) from the World Wide Web Consortium (W3C). + +In the IOTA Identity framework, we have implemented the DID standard according to the `iota` [DID Method Specification](../references/specifications/iota-did-method-spec.mdx). Other implementations of DID on IOTA must follow the `iota` DID Method Specification if they want to use the `iota` method name. Libraries implementing the `iota` DID Method Specification are provided for [Rust](../getting-started/rust.mdx) and [WASM](../getting-started/wasm.mdx). + +An example of a DID conforming to the `iota` method specification: +`did:iota:0xe4edef97da1257e83cbeb49159cfdd2da6ac971ac447f233f8439cf29376ebfe` + +## Decentralized Identifiers + +A Decentralized Identifier, or DID, is a unique identifier that is tied to a subject. This subject can be anything, like a person, an organization, an IoT device, or even an object. The identifier can be used by the subject to identify themselves through a digital format, providing a basis for online identification. The identifier looks like a set of random characters that includes some prefixes to determine which standard and implementation is used: + +`did:iota:0xe4edef97da1257e83cbeb49159cfdd2da6ac971ac447f233f8439cf29376ebfe` + +The World Wide Web Consortium (W3C) is a well-known standardization body that has standardized how DIDs should look and work. +This provides a basis for different technologies that implement the [DID standard](https://www.w3.org/TR/did-spec-registries/#did-methods) to achieve interoperability. +Keep in mind that, unfortunately, most of these methods are outdated and not maintained. + +## DID Documents + +The purpose of a DID is to help navigate to a DID Document, +which is a document containing more information regarding the identity subject. +This document contains data such as public keys, enabling the subject to prove ownership over their personal data, +but can contain additional information on how to interact with the subject. + +The identifier contains all information to resolve a DID, providing the latest DID Document. +The first three characters `did` indicate that the DID standard from W3C must be used to resolve the identifier. +It is followed by a unique method name, in our case `iota`, to indicate that the IOTA method is used. + +The IOTA method is a specific implementation following the [IOTA DID Method Specification](../references/specifications/iota-did-method-spec.mdx). +This provides unique rules for the protocol to follow in order to manage a DID Document. +In our case, it describes how DID Documents are uploaded and queried to and from the IOTA ledger. + +Lastly, a DID also contains a set of random characters that are unique per identity and resolve to a single DID Document. + +:::tip Requires basic knowledge of Asymmetric Encryption + +The following sections require some basic knowledge of Asymmetric Encryption. +Please read or view some materials on the subject before continuing. + +::: + +### DID Document Anatomy + +A DID Document mostly contains two important pieces of data: verification methods and services. + +#### Verification Methods + +Verification methods contain public key material that can be used to prove ownership over the identity, +by cryptographically signing something with the associated private key. +The public key can be used to verify that the identity subject signed the data and therefore controls the private key. +Ownership over the private keys, therefore, proves ownership over the identity. + +This also means that it is very important to keep the private keys safe and secure. +In addition, the public keys allow users to send encrypted data to the identity that only the identity owner can decrypt. + +:::caution + +Never share your private keys, seeds, passphrases with anyone. Not even IOTA Foundation members. +This may lead to loss of funds or control over your own digital identity. + +::: + +#### Services + +Services are URIs that point to more information about the identity. +This could be something as simple as a website for an organizational identity. +These services are publicly available for all to read, +and should not contain Personal Identifiable Information (PII) in the case of human identities. + +## Why Use DIDs? + +DIDs allow any subject to have a unique identifier that they can prove ownership of, +and at the same time provide a way to send them encrypted messages. +The Identity is Self-Sovereign, meaning the subject is always in control; +whether it is [creating](../how-tos/decentralized-identifiers/create.mdx), [updating](../how-tos/decentralized-identifiers/update.mdx), or [destroying](../how-tos/decentralized-identifiers/delete.mdx) it. + +### Verifiable Credentials + +DIDs become more interesting when you combine them with [verifiable credentials (VC)](verifiable-credentials.mdx). +In essence, verifiable credentials (VCs) are signed statements by trusted third parties about a certain identity. +The signer, or Issuer, is referenced by the DID and so is the subject, often called the holder. +The holder controls a copy of this statement and can share it with other parties, the _Verifiers_, +who can verify the statement and check which party made the statement without asking the Issuer. +Instead, they can verify the issuer's signature by checking the issuer's DID Document. + +This puts Holders back in control over their own data, +while making the data much more trustworthy as it has become verifiable. + +## Why Use Iota Identity Over Other Implementations? + +IOTA Identity is a framework to implement Self-Sovereign Identities on IOTA. +Inherently, IOTA provides some unique features that have a major impact on the usability of the framework. + +### Availability and Accessibility + +DID Documents are stored in the ledger state and are covered [storage deposit](/learn/protocols/stardust/core-concepts/storage-deposit/). +This guarantees that all nodes will have an up-to-date copy of the latest DID Document. +Resolving a DID into its document can usually be done by any IOTA node in the network. +This solves many issues regarding availability, accessibility, and synchronization. + +### Layer1 Interactions + +DID Documents are stored in [Alias Outputs](./about-alias-outputs.mdx), +this allows them to directly interact with Layer 1 artifacts like [NFTs and native assets](/learn/protocols/stardust/core-concepts/multi-asset-ledger/). + +For instance, an Alias Output representing a DID can hold native assets or control NFTs. +Transferring funds between DIDs is also possible on Layer 1. + +### Ease-of-use + +IOTA Identity abstracts the details of the DID standard by providing easy-to-use APIs that allow standardized behavior. +It also allows more flexible and complex management of DID Documents. + +### Secure Storage + +IOTA Identity provides a +[Stronghold](/stronghold.rs/welcome/ 'Stronghold is an open-source software library that was originally built to protect IOTA Seeds, but can be used to protect any digital secret.') solution +for managing secrets securely, without requiring developers to reinvent the security wheel. diff --git a/docs/content/guides/developer/iota-identity/explanations/verifiable-credentials.mdx b/docs/content/guides/developer/iota-identity/explanations/verifiable-credentials.mdx new file mode 100644 index 00000000000..708e04d8289 --- /dev/null +++ b/docs/content/guides/developer/iota-identity/explanations/verifiable-credentials.mdx @@ -0,0 +1,74 @@ +--- +description: Verifiable credentials are statements about the holder. They can be verified online or in person, and the holder decides who to share them with. +image: /img/Identity_icon.png +tags: + - verifiable + - credentials + - person +--- +# Verifiable Credentials + +:::info TL;DR + +Verifiable credentials (VCs) are digital statements that can be cryptographically proven, like a digital passport, +and are used within systems to assert certain properties or capabilities of an entity. + +In the IOTA Identity framework, this is managed with decentralized identifiers (DIDs) on the Tangle. +Subjects and issuers use their DIDs for the creation and verification of credentials. + +::: + +Credentials are statements about an entity, +such as properties that the entity possesses or capabilities that they have, +like a driver's license, passports, or a person's age. +Verifiable credentials (VCs) are statements (e.g., Alice has a driver's license) +that can be cryptographically verified by a third party, either online or in person. +Additionally, the holder of the VC decides what is shared and who it is shared with. + +There are several types of actors that play different roles in a Verifiable Credential system. +We'll start with a common example of how things work in the world today using physical credentials and centralized databases, +and outline the roles that various entities play in the Verifiable Credential system. + +## Example - Passport Issuance + +A government (the _issuer_) issues a passport asserting citizenship (the _Verifiable Credential_) to Alice (the _subject_ and _Holder_), +and writes the information to a database (the _Verifiable Data Registry_). +When crossing the border, Alice (the _Holder_) presents her passport to a border agent (the _Verifier_), +who can verify that Alice (the _subject_) is indeed a citizen. + + + +**Subject:** An entity about which claims are made – in this example, that Alice (the _subject_) is a citizen of this country. + +**Holder:** Any entity with a verifiable credential – Alice (the _Holder_) possesses the passport (the _VC_). + +**Issuer:** An entity which asserts claims about a subject – The governing body (the _issuer_), which is trusted, issues Alice a passport. + +**Verifier:** An entity which checks if the VC a holder presents is legitimate – The border agent (the _Verifier_) trusts the government (the _issuer_) which issued Alice her passport and validates that Alice (the _subject_) is a citizen. + +:::note + +See the [Verifiable Credentials Data Model 1.0 Specification](https://w3c.github.io/vc-data-model/) for more information. + +::: + +## Verifiable Credentials in IOTA + +In the IOTA Identity framework, instead of a physical passport being given to Alice and its information written +into a centralized database owned by the government, Alice receives a digital verifiable credential, +and the information required for verification in the future is written to the Tangle. + +At a high level, the creation and verification of a VC on IOTA works as follows: + + +The first step is to create a verifiable credential that requires the subject (Alice) and issuer (the government) to +have [DIDs](./decentralized-identifiers.mdx) published on the Tangle and a set of statements being asserted (that Alice has a passport). +The issuer signs the credential with their private key and publishes the public key to the Tangle. + +Once the issuer is confident that the credential satisfies its expectations, +the credential is stored and transmitted to the subject in a secure manner (off-chain). + +Validation is performed by looking up the issuer's public key on the Tangle, +the holder proving ownership of their DID to the verifier (evidence), +and validating that the issuing party has indeed signed the credential. + diff --git a/docs/content/guides/developer/iota-identity/explanations/verifiable-presentations.mdx b/docs/content/guides/developer/iota-identity/explanations/verifiable-presentations.mdx new file mode 100644 index 00000000000..a0a68dafc3e --- /dev/null +++ b/docs/content/guides/developer/iota-identity/explanations/verifiable-presentations.mdx @@ -0,0 +1,39 @@ +# Verifiable Presentations + +A verifiable presentation is the recommended data format for sharing one or more [verifiable credentials](./verifiable-credentials.mdx). +It is constructed and signed by a holder to prove control over their credentials and can be presented to a verifier for [validation](#validation). + +For instance, after an issuer [creates and issues](./../how-tos/verifiable-credentials/create.mdx) a [verifiable credential](./verifiable-credentials.mdx) to a holder, such as a university issuing a degree to a graduate, +the holder stores it securely until asked to present it. +A company could then request proof of that university degree: the holder can [create a verifiable presentation](./../how-tos/verifiable-credentials/create.mdx) +containing their credential, already signed by their university, and present it to the company to [validate](./../how-tos/verifiable-credentials/create.mdx#validate-a-vc). + +Note that verifiable presentations that contain personal data should, as with verifiable credentials, be transmitted and stored securely off-chain to satisfy data privacy regulations such as [GDPR](https://gdpr.eu/). + +:::note + +See the [Verifiable Credentials Data Model Specification](https://www.w3.org/TR/vc-data-model/#presentations) for more information on verifiable presentations. + +::: + +## Security Considerations + +### Replay Attacks + +A malicious actor could potentially store a verifiable presentation without a challenge +and replayed to a different verifier, impersonating the holder. +This is because the holder's signature on a presentation would still be seen as valid indefinitely, +until they [rotate](https://www.w3.org/TR/did-core/#verification-method-rotation) the verification method used. + +To mitigate this, verifiers should always send a unique challenge when requesting a verifiable presentation. +This challenge can be set as the `nonce` property of the JWS by the holder during signing. +The digital signature prevents these properties from being altered as it would invalidate the signature, effectively preventing a malicious +actor from injecting different values into old verifiable presentations. A presentation without a challenge in its proof that matches what was +sent by the verifier should be considered invalid. + +The challenge string should be sufficiently random and unique for each verifiable presentation requested by a verifier to avoid +being predicted. + +Holders may additionally specify that their signature on a verifiable presentation expires after a short duration, as +per `JwtPresentationOptions`. However, verifiers and different implementations could ignore that property, +so setting a signature expiration alone should not be relied upon. diff --git a/docs/content/guides/developer/iota-identity/faq.mdx b/docs/content/guides/developer/iota-identity/faq.mdx new file mode 100644 index 00000000000..d611f9dfa94 --- /dev/null +++ b/docs/content/guides/developer/iota-identity/faq.mdx @@ -0,0 +1,53 @@ +--- +title: Frequently Asked Questions +sidebar_label: FAQ +description: Frequently Asked Question regarding IOTA Identity. +image: /img/Identity_icon.png +tags: + - FAQ + - Frequently Asked Question + - Troubleshooting + - IOTA Identity +--- + +This page contains frequently asked questions regarding the Identity Library and Self-Sovereign Identity in general. + +### What programming languages are supported by the IOTA Identity framework? + +We currently provide a Rust library and a JavaScript library for both the browser and Node.js via WebAssembly (Wasm) bindings. See the "Programming Languages" section for more information. + +### Do I need to have IOTA tokens to start building with IOTA Identity? + +You need IOTA tokens to create identities, in order to pay the storage deposit. + +### How do I prove control over my DID? + +Control over an identity is ultimately tied to the control over cryptographic key material (something you have). + +### How do I store my private keys? + +Theoretically, you can store the keys however you like. Where possible, we provide a secure default using IOTA Stronghold, a secure software implementation for isolating digital secrets with encrypted storage. For even better guarantees, you could look into hardware-based key storage. + +### Do I need a Permanode to use IOTA Identity? + +You can get started without one, but currently, you require access to a Permanode (a node that stores the entire history of the Tangle) to reliably resolve the history of identities. + +### Can I use IOTA Identity on Android or iOS? + +We currently do not supply dedicated bindings for Kotlin or Swift. There has been some success running the Wasm bindings on mobile, however. + +### Can I use IOTA Identity on embedded devices? + +We currently do not supply dedicated bindings catering to embedded devices with restricted capabilities. You can try to compile the Rust library for your target platform or use a gateway in front of the devices to handle IOTA Identity interactions. + +### What should I do if my private key is compromised? + +If you still have control over your identity, rotate the key material ASAP! If an attacker has locked you out of your identity, there is not much you can do. Notify contacts that your identity has been compromised and start fresh with a new one. For this reason, we suggest using different keys for day-to-day signing and authentication operations and instead storing private keys capable of updating your DID Document securely and separately. + +### Are verifiable credentials stored on the Tangle? + +Verifiable credentials, particularly those with personal identifiable information, are supposed to be stored securely off-Tangle on user devices or systems. As a user, you are in charge of storing your credentials securely and sharing them with other parties on a need-to-know basis. + +### Do I need to hide my DID? Will people be able to identify me by my DID? + +A DID Document should not contain any information linking back to you as a person. However, there is the chance of entities correlating information about you from your DID if used across multiple issuers and verifiers. To minimize this risk, it is advisable to use different DIDs for different use cases. diff --git a/docs/content/guides/developer/iota-identity/getting-started/rust.mdx b/docs/content/guides/developer/iota-identity/getting-started/rust.mdx new file mode 100644 index 00000000000..ab6e3296cdb --- /dev/null +++ b/docs/content/guides/developer/iota-identity/getting-started/rust.mdx @@ -0,0 +1,68 @@ +--- +sidebar_label: Rust +description: Getting started with the IOTA Identity Rust Library. +image: /img/Identity_icon.png +tags: + - Rust + - Identity +--- +# Getting Started with Rust + +## Requirements + +- [Rust](https://www.rust-lang.org/) (>= 1.62) +- [Cargo](https://doc.rust-lang.org/cargo/) (>= 1.62) + +## Include the Library + +To include IOTA Identity in your project, add it as a dependency in your `Cargo.toml`: + +### Latest Stable Release + +This version is published to crates.io and is **stable**, following semantic versioning. + +```toml +[dependencies] +identity_iota = { version = "1.2.0" } +``` + +### Development Release + +This version matches the `main` branch of this repository. It has all the **latest features**, but as such, it **may also have undocumented breaking changes**. + +```toml +[dependencies] +identity_iota = { git = "https://github.com/iotaledger/identity.rs", branch = "main"} +``` + +## Examples + +To try out the [examples](https://github.com/iotaledger/identity.rs/tree/v1.2.0/examples), you should: + +1. Clone the repository: + +```bash +git clone https://github.com/iotaledger/identity.rs +``` + +2. Build the repository: + +```bash +cargo build +``` + +3. Run your first example: + +```bash +cargo run --example 0_create_did +``` + +## API Reference + +You can find the API reference for the Rust library on [docs.rs](https://docs.rs/identity_iota/latest/identity_iota/index.html). + +If you would like to build the documentation, locally you can do so with the following command: + +``` +RUSTDOCFLAGS='--cfg docsrs' cargo +nightly doc -p identity_iota --all-features --no-deps --open +``` diff --git a/docs/content/guides/developer/iota-identity/getting-started/wasm.mdx b/docs/content/guides/developer/iota-identity/getting-started/wasm.mdx new file mode 100644 index 00000000000..ad1baaf48d3 --- /dev/null +++ b/docs/content/guides/developer/iota-identity/getting-started/wasm.mdx @@ -0,0 +1,339 @@ +--- +sidebar_label: Wasm +description: Getting started with the IOTA Identity WASM Library. +image: /img/Identity_icon.png +tags: + - WASM + - install + - npm + - yarn + - build + - nodejs + - webpack +--- +# Getting Started with Wasm + +## Minimum Requirements + +- [Node.js](https://nodejs.org/en) (>= `v16`) + +## Install the Library + +You can install the latest stable version of the library by running the following command: + +```bash npm2yarn +npm install @iota/identity-wasm +``` + +## Build the Library + +Alternatively, you can build the bindings yourself if you have Rust installed. +If not, refer to [rustup.rs](https://rustup.rs) for the installation. + +### Requirements + +- [Node.js](https://nodejs.org/en) (>= `v16`) +- [Rust](https://www.rust-lang.org/) (>= 1.62) +- [Cargo](https://doc.rust-lang.org/cargo/) (>= 1.62) + +### 1. Install `wasm-bindgen-cli` + +If you want to build the library from source, +you will first need to manually install [`wasm-bindgen-cli`](https://github.com/rustwasm/wasm-bindgen). +A manual installation is required because we use the [Weak References](https://rustwasm.github.io/wasm-bindgen/reference/weak-references.html) feature, +which [`wasm-pack` does not expose](https://github.com/rustwasm/wasm-pack/issues/930). + +```bash +cargo install --force wasm-bindgen-cli +``` + +### 2. Install Dependencies + +After installing `wasm-bindgen-cli`, you can install the necessary dependencies using the following command: + +```bash npm2yarn +npm install +``` + +### 3. Build + + + + + +You can build the bindings for `node.js` using the following command: + +```bash npm2yarn +npm run build:nodejs +``` + + + + + +You can build the bindings for the `web` using the following command: + +```bash npm2yarn +npm run build:web +``` + + + + +## NodeJS Usage + +The following code creates a new IOTA DID Document suitable for publishing to a local test network, like the +[IOTA Sandbox](/iota-sandbox/welcome/). + + + + +```typescript +const { + KeyPair, + KeyType, + MethodScope, + IotaDocument, + IotaVerificationMethod, + IotaService, + MethodRelationship, + IotaIdentityClient, +} = require('@iota/identity-wasm/node'); +const { Client } = require('@iota/client-wasm/node'); + +// The endpoint of the IOTA node to use. +const API_ENDPOINT = 'http://127.0.0.1:14265'; + +/** Demonstrate how to create a DID Document. */ +async function main() { + // Create a new client with the given network endpoint. + const client = new Client({ + primaryNode: API_ENDPOINT, + localPow: true, + }); + + const didClient = new IotaIdentityClient(client); + + // Get the Bech32 human-readable part (HRP) of the network. + const networkHrp = await didClient.getNetworkHrp(); + + // Create a new DID document with a placeholder DID. + // The DID will be derived from the Alias Id of the Alias Output after publishing. + const document = new IotaDocument(networkHrp); + + // Insert a new Ed25519 verification method in the DID document. + let keypair = new KeyPair(KeyType.Ed25519); + let method = new IotaVerificationMethod( + document.id(), + keypair.type(), + keypair.public(), + '#key-1', + ); + document.insertMethod(method, MethodScope.VerificationMethod()); + + // Attach a new method relationship to the existing method. + document.attachMethodRelationship( + document.id().join('#key-1'), + MethodRelationship.Authentication, + ); + + // Add a new Service. + const service = new IotaService({ + id: document.id().join('#linked-domain'), + type: 'LinkedDomains', + serviceEndpoint: 'https://iota.org/', + }); + document.insertService(service); + + console.log(`Created document `, JSON.stringify(document.toJSON(), null, 2)); +} + +main(); +``` + +### Expected Output + +``` +Created document { + "doc": { + "id": "did:iota:0x0000000000000000000000000000000000000000000000000000000000000000", + "verificationMethod": [ + { + "id": "did:iota:0x0000000000000000000000000000000000000000000000000000000000000000#key-1", + "controller": "did:iota:0x0000000000000000000000000000000000000000000000000000000000000000", + "type": "Ed25519VerificationKey2018", + "publicKeyMultibase": "z4SxypezRxr1YdMAJBePfHGxZ9hNZ53WVixZq3PbUcztW" + } + ], + "authentication": [ + "did:iota:0x0000000000000000000000000000000000000000000000000000000000000000#key-1" + ], + "service": [ + { + "id": "did:iota:0x0000000000000000000000000000000000000000000000000000000000000000#linked-domain", + "type": "LinkedDomains", + "serviceEndpoint": "https://iota.org/" + } + ] + }, + "meta": { + "created": "2022-09-09T11:29:32Z", + "updated": "2022-09-09T11:29:32Z" + } +} +``` + +## Web Usage + +### Set Up + +The library loads the WASM file with an HTTP GET request, so you must copy the `.wasm` file the root of the `dist` folder. + +#### Rollup + +- Install `rollup-plugin-copy`: + +```bash npm2yarn +npm install rollup-plugin-copy --save-dev +``` + +- Add the copy plugin usage to the `plugins` array under `rollup.config.js`: + +```js +// Include the copy plugin +import copy from 'rollup-plugin-copy'; + +// Add the copy plugin to the `plugins` array of your rollup config: +copy({ + targets: [ + { + src: 'node_modules/@iota/client-wasm/web/wasm/client_wasm_bg.wasm', + dest: 'public', + rename: 'client_wasm_bg.wasm', + }, + { + src: 'node_modules/@iota/identity-wasm/web/identity_wasm_bg.wasm', + dest: 'public', + rename: 'identity_wasm_bg.wasm', + }, + ], +}); +``` + +#### Webpack + +- Install `copy-webpack-plugin`: + +```bash npm2yarn +npm install copy-webpack-plugin --save-dev +``` + +```js +// Include the copy plugin +const CopyWebPlugin= require('copy-webpack-plugin'); + +// Add the copy plugin to the `plugins` array of your webpack config: + +new CopyWebPlugin({ + patterns: [ + { + from: 'node_modules/@iota/client-wasm/web/wasm/client_wasm_bg.wasm', + to: 'client_wasm_bg.wasm' + }, + { + from: 'node_modules/@iota/identity-wasm/web/identity_wasm_bg.wasm', + to: 'identity_wasm_bg.wasm' + } + ] +}), +``` + +### Web Usage Example + +```typescript +import * as client from '@iota/client-wasm/web'; +import * as identity from '@iota/identity-wasm/web'; + +/** Demonstrate how to create a DID Document. */ +async function createDocument() { + // Create a new client with the given network endpoint. + const iotaClient = new client.Client({ + primaryNode: API_ENDPOINT, + localPow: true, + }); + + const didClient = new identity.IotaIdentityClient(iotaClient); + + // Get the Bech32 human-readable part (HRP) of the network. + const networkHrp = await didClient.getNetworkHrp(); + + // Create a new DID document with a placeholder DID. + // The DID will be derived from the Alias Id of the Alias Output after publishing. + const document = new identity.IotaDocument(networkHrp); + + // Insert a new Ed25519 verification method in the DID document. + let keypair = new identity.KeyPair(identity.KeyType.Ed25519); + let method = new identity.IotaVerificationMethod( + document.id(), + keypair.type(), + keypair.public(), + '#key-1', + ); + document.insertMethod(method, identity.MethodScope.VerificationMethod()); + + // Attach a new method relationship to the existing method. + document.attachMethodRelationship( + document.id().join('#key-1'), + identity.MethodRelationship.Authentication, + ); + + // Add a new Service. + const service = new identity.IotaService({ + id: document.id().join('#linked-domain'), + type: 'LinkedDomains', + serviceEndpoint: 'https://iota.org/', + }); + document.insertService(service); + + console.log(`Created document `, JSON.stringify(document.toJSON(), null, 2)); +} + +client + .init() + .then(() => identity.init()) + .then(() => { + await createDocument(); + }); + +// or + +(async () => { + await client.init(); + await identity.init(); + + await createDocument(); +})(); + +// Default path is "identity_wasm_bg.wasm", but you can override it like this +await identity.init('./static/identity_wasm_bg.wasm'); +``` + +You need to call `identity.init().then()`, +or `await identity.init()` to load the Wasm file from the server if not available, +because of that **it will only be slow for the first time**. + +## Examples in the Wild + +You may find it useful to see how the WASM bindings are being used in existing applications: + +- [Zebra IOTA Edge SDK](https://github.com/ZebraDevs/Zebra-Iota-Edge-SDK) (mobile apps using Capacitor.js + Svelte) + +## [API Reference](../references/api/wasm.mdx) + +## [Examples](https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/README.md) diff --git a/docs/content/guides/developer/iota-identity/glossary.mdx b/docs/content/guides/developer/iota-identity/glossary.mdx new file mode 100644 index 00000000000..54c79d76b62 --- /dev/null +++ b/docs/content/guides/developer/iota-identity/glossary.mdx @@ -0,0 +1,141 @@ +--- +description: Glossary for IOTA Identity, defines the terms used in this specification and throughout decentralized identifier infrastructure. +image: /img/Identity_icon.png +tags: + - W3C + - terminology + - IOTA + - verification method + - verifiable data registry + - reference +--- + +# Glossary + +This section defines the terms used in this specification, [sourced from W3](https://www.w3.org/TR/did-core/#terminology), and throughout decentralized identifier infrastructure. A link to these terms is included whenever they appear in this specification. + +The first part of the glossary describes the terminology by the W3C. The [second describes](#iota-terminology) the terminology for IOTA-related topics. + +## W3C Terminology + +### Authentication + +A process (typically some type of protocol) by which an entity can prove it has a specific attribute or controls a specific secret using one or more verification methods. With DIDs, a common example would be proving control of the private key associated with a public key published in a DID document. + +### Decentralized Identifier (DID) + +A globally unique persistent identifier that does not require a centralized registration authority because it is generated or registered cryptographically. The generic format of a DID is defined in the DID Core specification. A specific DID scheme is defined in a DID method specification. Many, but not all, DID methods make use of distributed ledger technology (DLT) or some other form of decentralized network. + +### Decentralized Identity Management + +A type of identity management that is based on the use of decentralized identifiers. Decentralized identity management extends authority for identifier generation, registration, and assignment beyond traditional roots of trust, such as X.500 directory services, the Domain Name System, and most national ID systems. + +### DID Controller + +An entity that can make changes to a DID document. A DID may have more than one DID controller. The DID controller(s) can be denoted by the optional controller property at the top level of the DID document. Note that one DID controller may be the DID subject. + +### DID Delegate + +An entity to whom a DID controller has granted permission to use a verification method associated with a DID via a DID document. For example, a parent who controls a child's DID document might permit the child to use their personal device for authentication purposes. In this case, the child is the DID delegate. The child's personal device would contain the private cryptographic material enabling the child to authenticate using the DID. However, the child may not be permitted to add other personal devices without the parent's permission. + +### DID Document + +A set of data describing the DID subject, including mechanisms, such as public keys and pseudonymous biometrics, that the DID subject or a DID delegate can use to authenticate itself and prove its association with the DID. A DID document may also contain other attributes or claims describing the DID subject. A DID document may have one or more different representations as defined in [§ 6. Representations](https://www.w3.org/TR/did-core/#representations) or in the W3C DID Specification Registries [DID-SPEC-REGISTRIES](https://www.w3.org/TR/did-core/#bib-did-spec-registries). + +### DID Fragment + +The portion of a DID URL that follows the first hash sign character (#). DID fragment syntax is identical to URI fragment syntax. + +### DID Method + +A definition of how a specific DID scheme must be implemented to work with a specific verifiable data registry. A DID method is defined by a DID method specification, which must specify the precise operations by which DIDs are created, resolved, and deactivated, where DID documents are written and updated. [See W3's Methods](https://www.w3.org/TR/did-core/#methods). + +### DID Path + +The portion of a DID URL that begins with and includes the first forward-slash (/) character and ends with either a question mark (?) character or a fragment hash sign (#) character (or the end of the DID URL). DID path syntax is identical to URI path syntax. See [Path](https://www.w3.org/TR/did-core/#path). + +### DID Query + +The portion of a DID URL that follows and includes the first question mark character (?). DID query syntax is identical to URI query syntax. See [Query](https://www.w3.org/TR/did-core/#query). + +### DID Resolution + +The function that takes, as an input, a DID and a set of input metadata and returns a DID document in a conforming representation plus additional metadata. This function relies on the "Read" operation of the applicable DID method. The inputs and outputs of this function are defined in [Resolution](https://www.w3.org/TR/did-core/#resolution). + +### DID Resolver + +A DID resolver is a software or hardware component that performs the DID resolution function by taking a DID as input and producing a conforming DID document as output. + +### DID Scheme + +The formal syntax of a decentralized identifier. The generic DID scheme begins with the prefix "did:" as defined in the section of the DID Core specification. Each DID method specification must define a specific DID scheme that works with that particular DID method. In a specific DID method scheme, the DID method name must follow the first colon and terminate with the second colon, such as "did:example:". + +### DID Subject + +The entity identified by a DID and described by a DID document. A DID has exactly one DID subject. Anything can be a DID subject: a person, group, organization, physical thing, digital thing, logical thing, and so on. + +### DID URL + +A DID plus any additional syntactic component that conforms to the definition in § 3.2 DID URL Syntax. This includes an optional DID path, optional DID query (and its leading ? character), and optional DID fragment (and its leading # character). + +### DID URL Dereferencing + +The function that takes as its input a DID URL, a DID document, plus a set of dereferencing options, and returns a resource. This resource may be a DID document plus additional metadata, or it may be a secondary resource contained within the DID document, or it may be a resource entirely external to the DID document. If the function begins with a DID URL, it uses the DID resolution function to fetch a DID document indicated by the DID contained within the DID URL. The dereferencing function can then perform additional processing on the DID document to return the dereferenced resource indicated by the DID URL. The inputs and outputs of this function are defined in [DID URL Dereferencing](https://www.w3.org/TR/did-core/#did-url-dereferencing). + +## IOTA Terminology + +### Distributed Ledger (DLT) + +A distributed database in which the various nodes use a consensus protocol to maintain a shared ledger in which each transaction is cryptographically signed and chained to the previous transaction. + +### Public Key Description + +A data object contained inside a DID document that contains all the metadata necessary to use a public key or verification key. + +### Resource + +As defined by [RFC3986](https://www.rfc-editor.org/rfc/rfc3986): "...the term 'resource' is used in a general sense for whatever might be identified by a URI." Similarly, any resource may serve as a DID subject identified by a DID + +### Representation + +As defined for HTTP by [RFC7231](https://httpwg.org/specs/rfc7231.html): "information that is intended to reflect a past, current, or desired state of a given resource, in a format that can be readily communicated via the protocol, and that consists of a set of representation metadata and a potentially unbounded stream of representation data." A DID document is a representation of information describing a DID subject. The [Representations](https://www.w3.org/TR/did-core/#representations) section of the DID Core specification defines several representation formats for a DID document. + +### Service + +A means of communicating or interacting with the DID subject or associated entities via one or more service endpoints. Examples include discovery services, agent services, social networking services, file storage services, and verifiable credential repository services. + +### Service Endpoint + +A network address (such as an HTTP URL) at which a service operates on behalf of a DID subject. + +### Uniform Resource Identifier (URI) + +The standard identifier format for all resources on the World Wide Web as defined by [RFC3986](https://www.rfc-editor.org/rfc/rfc3986). A DID is a type of URI scheme. + +### Verifiable Credential + +A standard data model and representation format for cryptographically-verifiable digital credentials as defined by the W3C [VC-DATA-MODEL](https://www.w3.org/TR/vc-data-model/). + +### Verifiable Data Registry + +A system that facilitates the creation, verification, updating, or deactivation of decentralized identifiers and DID documents. A verifiable data registry may also be used for other cryptographically-verifiable data structures, such as verifiable credentials. For more information, see [VC-DATA-MODEL](https://www.w3.org/TR/vc-data-model/). + +### Verifiable Timestamp + +A verifiable timestamp enables a third-party to verify that a data object existed at a specific moment in time and that it has not been modified or corrupted since that moment in time. If the data integrity were to be reasonably modified or corrupted since that moment in time, the timestamp is not verifiable. + +### Verification Method + +A set of parameters that can be used together with a process or protocol to independently verify a proof. For example, a public key can be used as a verification method with respect to a digital signature; in such usage, it verifies that the signer possessed the associated private key. + +"Verification" and "proof" in this definition are intended to apply broadly. For example, a public key might be used during Diffie-Hellman key exchange to negotiate a shared symmetric key for encryption. This guarantees the integrity of the key agreement process. It is thus another type of verification method, even though descriptions of the process might not use the words "verification" or "proof." + +### Verification Relationship + +An expression of the relationship between the DID subject and a verification method. An example of a verification relationship is [authentication](https://www.w3.org/TR/did-core/#authentication). + +### Universally Unique Identifier (UUID) + +A type of globally unique identifier defined by [RFC4122](https://www.rfc-editor.org/rfc/rfc4122). UUIDs are similar to DIDs in that they do not require a centralized registration authority. UUIDs differ from DIDs in that they are not resolvable or cryptographically verifiable. +In addition to the terminology above, this specification also uses terminology from the [INFRA](https://infra.spec.whatwg.org/) specification to formally define the abstract data model. When [INFRA](https://infra.spec.whatwg.org/) terminology is used, such as string, ordered set, and map, it is linked directly to that specification. +In addition to the terminology above, this specification also uses terminology from the [INFRA] specification to formally define the abstract data model. When [INFRA] terminology is used, such as string, ordered set, and map, it is linked directly to that specification. diff --git a/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/create.mdx b/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/create.mdx new file mode 100644 index 00000000000..6266a8b26df --- /dev/null +++ b/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/create.mdx @@ -0,0 +1,180 @@ +--- +title: Creating a Decentralized Identity +sidebar_label: Create and Publish +description: Create DID Documents and publish them to the Tangle +image: /img/Identity_icon.png +tags: + - Documents + - DID + - Tangle + - Create + - Publish +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +If you want to benefit from Self-Sovereign Identity, +you need to create a [Decentralized Identity](../../explanations/decentralized-identifiers.mdx). +This identity consists of many parts that have different functions. + +:::note DID method Specification + +Note that the Iota Identity Framework follows [IOTA DID Method Specification](../../references/specifications/iota-did-method-spec.mdx). + +::: + +## Identity Generation Process + + +### 1. Get Funds to Cover the Storage Deposit + +The first thing you will need to generate an identity is an address with enough funds to cover +the [Storage Deposit](../../explanations/about-alias-outputs.mdx#storage-deposit). +In test networks, you can use a [faucet](https://faucet.testnet.shimmer.network/) to request funds. + +:::tip + +If you want to use the main Shimmer or IOTA networks, +you will need an output with actual Shimmer or IOTA funds to create a new Alias Output that represents a DID. + +::: + +
+ + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/0_basic/0_create_did.rs#L52 +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/0_basic/0_create_did.ts#L40-L51 +``` + + + +
+ +### 2. Create the Content for the DID Document + +As a bare minimum, a [DID document](../../explanations/decentralized-identifiers.mdx) needs at least one verification method. + +At this point, the DID itself is unknown since the Alias Output is not published yet and didn't get an `Alias ID` assigned. + +:::tip + +You can use a placeholder `did:iota:0x0000000000000000000000000000000000000000000000000000000000000000` to reference +the DID inside the document. + +::: + +
+ + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/0_basic/0_create_did.rs#L59-L71 +``` + + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/0_basic/0_create_did.ts#L55C44-L65 +``` + + + +
+ +### 3. Construct a New Alias Output + +Next, you need to construct a new [Alias Output](../../explanations/about-alias-outputs.mdx) that includes the +DID Document in the [State Metadata](../../explanations/about-alias-outputs.mdx). +The created Alias Output contains an encoded version of the DID Document in its `State Metadata`, and has the state +controller and the governor set to the generated Ed25519 address. + +Note that controllers don't need to be Ed25519 addresses, they can be any type of output. +However, they must be unlocked in order perform a state or governance transition when the DID Document is updated or destroyed. + + +
+ + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/0_basic/0_create_did.rs#L75 +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/0_basic/0_create_did.ts#L70 +``` + + + +
+ +### 4. Publish the generated Alias Output. + +The byte cost for the document is automatically calculated and a new transaction is published that includes +the Basic Output as input and the newly generated Alias Output as output, as well as another Basic Output which contains +the remaining tokens. + +The DID is only known once the [Alias Output](../../explanations/about-alias-outputs.mdx) is successfully published, +since the DID's [Tag](../../references/specifications/iota-did-method-spec.mdx#iota-tag) contains the +[Alias ID](../../explanations/about-alias-outputs.mdx#alias-id). +Once the transaction is confirmed, the `Alias ID` is assigned, and the DID can be derived from it, +the DID Document is stored on the ledger and can be [resolved](resolve.mdx) using any node. + + +
+ + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/0_basic/0_create_did.rs#L78 +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/0_basic/0_create_did.ts#L74 +``` + + + +
+ +## Full Example Code + + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/0_basic/0_create_did.rs +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/0_basic/0_create_did.ts +``` + + + + +## Running Examples Locally + +In order to run the examples, you will need to run the [IOTA Sandbox](/iota-sandbox/welcome/) locally. + +If you want to use something different, you will need to modify the API and faucet endpoints in the examples to match your +setup. \ No newline at end of file diff --git a/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/delete.mdx b/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/delete.mdx new file mode 100644 index 00000000000..86bb74c20a7 --- /dev/null +++ b/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/delete.mdx @@ -0,0 +1,106 @@ +--- +title: Delete an IOTA Identity +sidebar_label: Delete +description: How to deactivate or destroy an IOTA Identity +image: /img/Identity_icon.png +tags: + - Delete + - Deactivate + - Destroy +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +There are two approaches to delete an IOTA Identity, with different implications: + +- [Deactivate](#deactivate) +- [Destroy](#destroy) + +## Deactivate + +As detailed in the [IOTA DID Method Specification](../../references/specifications/iota-did-method-spec.mdx#deactivate), +the state controller of an IOTA Identity may [deactivate](https://www.w3.org/TR/did-core/#did-document-metadata) it by publishing an update that either: + +- deletes the contents of the DID Document entirely, leaving the state metadata empty, OR +- sets the `deactivated` field in the DID Document metadata to `true`. + +In both cases, the DID Document will be marked as `deactivated` when resolved. + +:::tip Reversible + +The identity can be reactivated at any time, by publishing an update restoring the DID Document's contents, +or unsetting the `deactivated` field in the metadata respectively, depending on how it was initially deactivated. + +Note that if the governor is different from the state controller, it cannot deactivate an identity directly because +it is disallowed from updating the DID Document, but it may [destroy](#destroy) it. + +::: + +### Example + +The following example demonstrates deactivating and reactivating an IOTA DID Document, +and optionally reclaiming the storage deposit. + + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/0_basic/3_deactivate_did.rs +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/0_basic/3_deactivate_did.ts +``` + + + + +## Destroy + +Alternatively, you can [destroy](../../references/specifications/iota-did-method-spec.mdx#destroy) an IOTA Identity can be permanently. + +:::warning Irreversible + +Destroying an IOTA Identity is permanent and irreversible. + +::: + + +This is achieved by the governor of a DID publishing a transaction consuming the [Alias Output](../../references/specifications/iota-did-method-spec.mdx#alias-output) +containing the IOTA DID Document, without a corresponding Alias Output on the output side. + +Any coins and tokens in the Alias Output are reclaimed and can be sent to another address. + +:::warning + +Note that historical versions may still be stored off-ledger, or on a permanode, +so sensitive or Personal Identifiable Information (PII) should NEVER be stored in a DID Document. + +::: + +Even with a previous version available, a destroyed DID can never be restored. + +### Example + +The following example demonstrates how a governor destroys an IOTA Identity and sends the storage deposit back to itself. + + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/0_basic/4_delete_did.rs +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/0_basic/4_delete_did.ts +``` + + + diff --git a/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/resolve.mdx b/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/resolve.mdx new file mode 100644 index 00000000000..1e5411f592d --- /dev/null +++ b/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/resolve.mdx @@ -0,0 +1,196 @@ +--- +title: Resolve an IOTA Identity +sidebar_label: Resolve +description: Explain how resolving works including arguments +image: /img/Identity_icon.png +tags: + - Resolve +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +DID resolution is the process of fetching and decoding a [DID Document](https://www.w3.org/TR/did-core/#dfn-did-documents) corresponding to a given [DID](https://www.w3.org/TR/did-core/#dfn-decentralized-identifiers). +The [IOTA Identity framework](https://github.com/iotaledger/identity.rs) supports resolving DID Documents that are +stored on the IOTA and Shimmer networks and enables users to plug in handlers for additional methods. + +This is similar to, but not to be confused with, +the [W3C DID Resolution specification](https://w3c-ccg.github.io/did-resolution/), +which defines function signatures for resolution in the context of web or REST APIs, +whereas the IOTA Identity framework provides strongly-typed resolution for a better developer experience. + +This functionality is primarily provided by the `Resolver`, which can: + +- [Resolve IOTA DID Documents](#resolving-an-iota-did). +- [Resolve DID Documents from multiple DID methods](#resolving-multiple-did-methods). +- Resolve the DID Documents referenced in a verifiable presentation or credential. + +## Resolving an IOTA DID + +The following examples demonstrate how to resolve an IOTA DID Document from its DID. + +### Resolver + +Once you have configured a `Resolver` with a [`Client`](/iota-sdk/welcome), it will resolve +IOTA DID Documents according to the read procedure defined in the [IOTA DID Method Specification](../../references/specifications/iota-did-method-spec.mdx#read). +It fetches the latest [Alias Output](../../references/specifications/iota-did-method-spec.mdx#alias-output) from the network specified in the DID (see [DID Format](../../references/specifications/iota-did-method-spec.mdx#did-format)), +then extracts and validates the DID Document from it. + + + + +```rust +use identity_iota::iota::IotaDID; +use identity_iota::iota::IotaDocument; +use identity_iota::resolver::Resolver; +use iota_sdk::client::Client; + +#[tokio::main] +async fn main() -> anyhow::Result<()>{ + // Configure a client for the Shimmer testnet "rms". + let node_url = "https://api.testnet.shimmer.network/"; + let client = Client::builder() + .with_primary_node(node_url, None)? + .finish()?; + + // Construct a resolver using the client. + let mut resolver = Resolver::::new(); + resolver.attach_iota_handler(client); + + // Parse the DID and resolve its DID Document. + let did = IotaDID::parse("did:iota:rms:0x7b48b06232b8a1e7a31c314cab1ceedb84e2e9dd2b1fae79b67eaa4595f15e47")?; + let document: IotaDocument = resolver.resolve(&did).await?; + + Ok(()) +} +``` + + + + +```js +const { + Resolver, + IotaDID, + IotaIdentityClient, +} = require('@iota/identity-wasm/node'); +const { Client } = require('@iota/client-wasm/node'); + +// Configure a client for the Shimmer testnet "rms". +const nodeUrl = 'https://api.testnet.shimmer.network/'; +const client = new Client({ + primaryNode: nodeUrl, + localPow: true, +}); +const didClient = new IotaIdentityClient(client); + +// Construct a resolver using the client. +const resolver = new Resolver({ + client: didClient, +}); + +// Resolve the given did +const did = + 'did:iota:rms:0x7b48b06232b8a1e7a31c314cab1ceedb84e2e9dd2b1fae79b67eaa4595f15e47'; +const document = await resolver.resolve(did); +``` + + + + +### Client + +You can also use the [`Client`](/iota-sdk/welcome) directly to resolve individual DIDs from its configured network. + + + + +```rust +use identity_iota::iota::IotaDID; +use identity_iota::iota::IotaDocument; +use identity_iota::iota::IotaIdentityClientExt; +use iota_sdk::client::Client; + +#[tokio::main] +async fn main() -> anyhow::Result<()>{ + // Configure a client for the Shimmer testnet "rms". + let node_url = "https://api.testnet.shimmer.network/"; + let client = Client::builder() + .with_primary_node(node_url, None)? + .finish()?; + + // Parse the DID and resolve its DID Document. + let did = IotaDID::parse("did:iota:rms:0x7b48b06232b8a1e7a31c314cab1ceedb84e2e9dd2b1fae79b67eaa4595f15e47")?; + let document: IotaDocument = client.resolve_did(&did).await?; + Ok(()) +} +``` + + + + +```js +const { IotaDID, IotaIdentityClient } = require('@iota/identity-wasm/node'); +const { Client } = require('@iota/client-wasm/node'); + +// Configure a client for the Shimmer testnet "rms". +const nodeUrl = 'https://api.testnet.shimmer.network/'; +const client = new Client({ + primaryNode: nodeUrl, + localPow: true, +}); +const didClient = new IotaIdentityClient(client); + +// Parse the DID and resolve its DID Document. +const did = IotaDID.parse( + 'did:iota:rms:0x7b48b06232b8a1e7a31c314cab1ceedb84e2e9dd2b1fae79b67eaa4595f15e47', +); +const document = await didClient.resolveDid(did); +``` + + + + +## Advanced Resolver Configuration + +You can configure the `Resolver` to support many use cases by attaching custom resolution handlers. +This enables the `Resolver` to resolve multiple DID methods, as well as customizing how +a particular DID method (such as the IOTA method) gets resolved. + +This feature is mainly intended to be used together with the Resolver's convenience methods for +handling [verifiable presentations](../verifiable-presentations/create-and-validate.mdx) +and [credentials](./../../explanations/verifiable-credentials.mdx). + +### Resolving Multiple DID Methods + + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/1_advanced/5_custom_resolution.rs +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/1_advanced/4_custom_resolution.ts +``` + + + + +## Resolution for Verifiable Presentations + +When validating [verifiable presentations](./../verifiable-presentations/create-and-validate.mdx), you need to +resolve the DID Documents of the [verifiable credential](./../../explanations/verifiable-credentials.mdx) issuers +and presentation holder to verify their signatures. + +Resolving the necessary DID Documents is +[performed automatically when verifying presentations via the `Resolver`](../verifiable-presentations/create-and-validate.mdx#example) + +When direct access to these DID Documents is desired, the `Resolver` also provides standalone methods to: + +- Resolve a presentation holder's DID Document. +- Resolve the DID Documents of the issuers of the credentials in a verifiable presentation. +- Resolve the issuer's DID Document for a given verifiable credential. diff --git a/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/update.mdx b/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/update.mdx new file mode 100644 index 00000000000..13e4dc22034 --- /dev/null +++ b/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/update.mdx @@ -0,0 +1,534 @@ +--- +sidebar_label: Update +description: How DID Documents can be manipulated and how updates should be published +image: /img/Identity_icon.png +tags: + - Documents + - DID + - Tangle + - Update + - Publish +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Update DID Documents + +You can extend DID Documents by adding [verification methods](#verification-methods), [services](#services) and custom properties. +A verification method adds public keys, which can be used to digitally sign things like a DID message or a verifiable credential, +while a service can provide metadata around the identity via URIs. + +## Verification Methods + +As demonstrated by the [example](#example) below, the IOTA Identity framework offers easy-to-use methods for adding +[verification methods](https://www.w3.org/TR/did-core/#verification-methods). + +### Properties + +You can specify the following properties for a verification method: + +- **id**: A [DID URL](https://www.w3.org/TR/did-core/#did-url-syntax) for the verification method. You can specify it by setting the [fragment](https://www.w3.org/TR/did-core/#fragment). +- **type**: Specifies the type of the verification method. The framework supports `Ed25519` and `X25519` key types. This property is automatically filled by the framework when specifying the verification material. +- **publicKeyMultibase**: A multi-base encoded public key which concludes the [verification material](https://www.w3.org/TR/did-core/#verification-material). This can be automatically generated by the framework or manually provided by users. + +## Verification Relationships + +[Verification relationships](https://www.w3.org/TR/did-core/#verification-relationships) express the relationship between the DID subject and the verification method. +You can use it to specify the purpose of the verification method. + +### Relationships + +The Identity Framework supports the following relationships: + +- **[Authentication](https://www.w3.org/TR/did-core/#authentication)**: Used to specify authentication methods for the DID subject. +- **[Assertion](https://www.w3.org/TR/did-core/#assertion)**: Used to verify verifiable credentials. +- **[Key Agreement](https://www.w3.org/TR/did-core/#assertion)**: Used for establishing secure communication channels. +- **[Capability Invocation](https://www.w3.org/TR/did-core/#capability-invocation)**: Can be used to authorize updates to the DID Document. +- **[Capability Delegation](https://www.w3.org/TR/did-core/#capability-delegation)**: A mechanism to delegate cryptographic capability to another party. + +Verification methods can be either [embedded or referenced](https://www.w3.org/TR/did-core/#referring-to-verification-methods). Referencing verification +methods allows them to be used by more than one verification relationship. +When you create a verification method using the Identity Framework, specifying the `MethodScope` option will result in an embedded verification method. +Leaving that option unset will create the verification method as a map entry of the `verificationMethod` property. +You can also add verification relationships afterward using references. + +:::note + +Updates to the DID Document are done through a state transition of the [Alias Output](../../references/specifications/iota-did-method-spec.mdx#alias-output) by its state controller. +The public key or address of the state controller does not need to be a verification method in the DID Document, +since it is defined in the containing Alias Output. + +::: + +## Services + +[Services](https://www.w3.org/TR/did-core/#services) allow you to add other ways of communicating with the DID subject. +An endpoint included in the DID Document can offer a way of reaching services for different purposes +like authentication, communicating, and discovery. + +### Properties + +You can specify the following properties for a service: + +- **id**: A [DID URL](https://www.w3.org/TR/did-core/#did-url-syntax) for referencing the service in the DID document. You can specify it by setting the [fragment](https://www.w3.org/TR/did-core/#fragment). +- **type**: A string used to maximize interoperability between services. The framework does not perform any checks on the content of this string. +- **serviceEndpoint**: A URL that points to the service endpoint. + +## Create Identity + +Before you can update anything, you will need to [create an Identity](./create.mdx). + + + + +```rust + // Create a new client to interact with the IOTA ledger. + let client: Client = Client::builder() + .with_primary_node(API_ENDPOINT, None)? + .finish() + .await?; + + // Create a new secret manager backed by a Stronghold. + let mut secret_manager: SecretManager = SecretManager::Stronghold( + StrongholdSecretManager::builder() + .password(Password::from("secure_password".to_owned())) + .build(random_stronghold_path())?, + ); + + // Create a new DID in an Alias Output for us to modify. + let storage: MemStorage = MemStorage::new(JwkMemStore::new(), KeyIdMemstore::new()); + let (_, document, fragment_1): (Address, IotaDocument, String) = + create_did(&client, &mut secret_manager, &storage).await?; + let did: IotaDID = document.id().clone(); + +``` + + + + +```js + const client = new Client({ + primaryNode: API_ENDPOINT, + localPow: true, + }); + const didClient = new IotaIdentityClient(client); + + // Generate a random mnemonic for our wallet. + const secretManager: MnemonicSecretManager = { + mnemonic: Utils.generateMnemonic(), + }; + + // Creates a new wallet and identity (see "0_create_did" example). + const storage: Storage = new Storage(new JwkMemStore(), new KeyIdMemStore()); + let { document, fragment } = await createDid( + client, + secretManager, + storage, + ); +``` + + + + +This creates and publishes an Alias Output containing a DID Document with one verification method. + +```json +{ + "doc": { + "id": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a", + "verificationMethod": [ + { + "id": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a#HZ11e0XacuODQw5FcoMHtcdxl8oXHbSnIhQMUgVzWBE", + "controller": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a", + "type": "JsonWebKey", + "publicKeyJwk": { + "kty": "OKP", + "alg": "EdDSA", + "kid": "HZ11e0XacuODQw5FcoMHtcdxl8oXHbSnIhQMUgVzWBE", + "crv": "Ed25519", + "x": "475CGLtezvySFMCHhx6hE9S97MIYMLb4B-pbVEHaCtY" + } + } + ] + }, + "meta": { + "created": "2023-11-16T20:40:03Z", + "updated": "2023-11-16T20:40:03Z", + "governorAddress": "tst1qrjsnlg6nqd2kdzx4q880nl74jtrcajm7ae57zazl0l7ye09ahh4x6z9gtd", + "stateControllerAddress": "tst1qrjsnlg6nqd2kdzx4q880nl74jtrcajm7ae57zazl0l7ye09ahh4x6z9gtd" + } +} +``` + +## Add a Verification Method + + + + +```rust + // Insert a new Ed25519 verification method in the DID document. + let fragment_2: String = document + .generate_method( + &storage, + JwkMemStore::ED25519_KEY_TYPE, + JwsAlgorithm::EdDSA, + None, + MethodScope::VerificationMethod, + ) + .await?; +``` + + + + +```js + // Insert a new Ed25519 verification method in the DID document. + await document.generateMethod( + storage, + JwkMemStore.ed25519KeyType(), + JwsAlgorithm.EdDSA, + "#key-2", + MethodScope.VerificationMethod(), + ); +``` + + + + +This creates a new verification method that includes a newly generated Ed25519 public key. + +```json +{ + "doc": { + "id": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a", + "verificationMethod": [ + { + "id": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a#HZ11e0XacuODQw5FcoMHtcdxl8oXHbSnIhQMUgVzWBE", + "controller": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a", + "type": "JsonWebKey", + "publicKeyJwk": { + "kty": "OKP", + "alg": "EdDSA", + "kid": "HZ11e0XacuODQw5FcoMHtcdxl8oXHbSnIhQMUgVzWBE", + "crv": "Ed25519", + "x": "475CGLtezvySFMCHhx6hE9S97MIYMLb4B-pbVEHaCtY" + } + }, + { + "id": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a#yJz-sPlCmd432JKqK_hkiPml2kj22Jv0aAFy_2jJ8nE", + "controller": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a", + "type": "JsonWebKey", + "publicKeyJwk": { + "kty": "OKP", + "alg": "EdDSA", + "kid": "yJz-sPlCmd432JKqK_hkiPml2kj22Jv0aAFy_2jJ8nE", + "crv": "Ed25519", + "x": "h8ndZ4_Urmzf4xN4emqS8r5q4pAQvAh0k2YHq5JLBBo" + } + } + ] + }, + "meta": { + "created": "2023-11-16T20:40:03Z", + "updated": "2023-11-16T20:40:03Z", + "governorAddress": "tst1qrjsnlg6nqd2kdzx4q880nl74jtrcajm7ae57zazl0l7ye09ahh4x6z9gtd", + "stateControllerAddress": "tst1qrjsnlg6nqd2kdzx4q880nl74jtrcajm7ae57zazl0l7ye09ahh4x6z9gtd" + } +} +``` + +Notice that these changes to the document are not [published](#publish-your-updates) yet. + +## Add Verification Relationships + +You can attach verification relationships to a verification method by referencing its fragment. + + + + +```rust +// Attach a new method relationship to the inserted method. +document.attach_method_relationship( + &document.id().to_url().join(format!("#{fragment_2}"))?, + MethodRelationship::Authentication, +)?; +``` + + + + +```js +// Attach a new method relationship to the inserted method. +document.attach_method_relationship( + &document.id().to_url().join(format!("#{fragment_2}"))?, + MethodRelationship::Authentication, +)?; +``` + + + + +This will add `Authentication` relationship to the verification method with the fragment `key-1`. +Note that `Authentication` references the already included `key-2` verification method: + +```json {12,19} +{ + "doc": { + "id": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a", + "verificationMethod": [ + { + "id": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a#HZ11e0XacuODQw5FcoMHtcdxl8oXHbSnIhQMUgVzWBE", + "controller": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a", + "type": "JsonWebKey", + "publicKeyJwk": { + "kty": "OKP", + "alg": "EdDSA", + "kid": "HZ11e0XacuODQw5FcoMHtcdxl8oXHbSnIhQMUgVzWBE", + "crv": "Ed25519", + "x": "475CGLtezvySFMCHhx6hE9S97MIYMLb4B-pbVEHaCtY" + } + }, + { + "id": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a#yJz-sPlCmd432JKqK_hkiPml2kj22Jv0aAFy_2jJ8nE", + "controller": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a", + "type": "JsonWebKey", + "publicKeyJwk": { + "kty": "OKP", + "alg": "EdDSA", + "kid": "yJz-sPlCmd432JKqK_hkiPml2kj22Jv0aAFy_2jJ8nE", + "crv": "Ed25519", + "x": "h8ndZ4_Urmzf4xN4emqS8r5q4pAQvAh0k2YHq5JLBBo" + } + } + ], + "authentication": [ + "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a#yJz-sPlCmd432JKqK_hkiPml2kj22Jv0aAFy_2jJ8nE" + ] + }, + "meta": { + "created": "2023-11-16T20:40:03Z", + "updated": "2023-11-16T20:40:03Z", + "governorAddress": "tst1qrjsnlg6nqd2kdzx4q880nl74jtrcajm7ae57zazl0l7ye09ahh4x6z9gtd", + "stateControllerAddress": "tst1qrjsnlg6nqd2kdzx4q880nl74jtrcajm7ae57zazl0l7ye09ahh4x6z9gtd" + } +} +``` + +## Add a Service + +You can also add custom properties can to a service by setting `properties`: + + + + +```rust + // Add a new Service. + let service: Service = Service::from_json_value(json!({ + "id": document.id().to_url().join("#linked-domain")?, + "type": "LinkedDomains", + "serviceEndpoint": "https://iota.org/" + }))?; + assert!(document.insert_service(service).is_ok()); + document.metadata.updated = Some(Timestamp::now_utc()); +``` + + + + +```js + // Add a new Service. + const service: Service = new Service({ + id: did.join("#linked-domain"), + type: "LinkedDomains", + serviceEndpoint: "https://iota.org/", + }); + document.insertService(service); + document.setMetadataUpdated(Timestamp.nowUTC()); +``` + + + + +The updated Document with the newly created service looks as follows. + +```json {21-27} +{ + "doc": { + "id": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a", + "verificationMethod": [ + { + "id": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a#HZ11e0XacuODQw5FcoMHtcdxl8oXHbSnIhQMUgVzWBE", + "controller": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a", + "type": "JsonWebKey", + "publicKeyJwk": { + "kty": "OKP", + "alg": "EdDSA", + "kid": "HZ11e0XacuODQw5FcoMHtcdxl8oXHbSnIhQMUgVzWBE", + "crv": "Ed25519", + "x": "475CGLtezvySFMCHhx6hE9S97MIYMLb4B-pbVEHaCtY" + } + }, + { + "id": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a#yJz-sPlCmd432JKqK_hkiPml2kj22Jv0aAFy_2jJ8nE", + "controller": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a", + "type": "JsonWebKey", + "publicKeyJwk": { + "kty": "OKP", + "alg": "EdDSA", + "kid": "yJz-sPlCmd432JKqK_hkiPml2kj22Jv0aAFy_2jJ8nE", + "crv": "Ed25519", + "x": "h8ndZ4_Urmzf4xN4emqS8r5q4pAQvAh0k2YHq5JLBBo" + } + } + ], + "authentication": [ + "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a#yJz-sPlCmd432JKqK_hkiPml2kj22Jv0aAFy_2jJ8nE" + ], + "service": [ + { + "id": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a#linked-domain", + "type": "LinkedDomains", + "serviceEndpoint": "https://iota.org/" + } + ] + }, + "meta": { + "created": "2023-11-16T20:40:03Z", + "updated": "2023-11-16T20:40:08Z", + "governorAddress": "tst1qrjsnlg6nqd2kdzx4q880nl74jtrcajm7ae57zazl0l7ye09ahh4x6z9gtd", + "stateControllerAddress": "tst1qrjsnlg6nqd2kdzx4q880nl74jtrcajm7ae57zazl0l7ye09ahh4x6z9gtd" + } +} +``` + +## Remove a Verification Method + +You can also remove verification methods at any time using the following snippet: + + + + +```rust +// Remove a verification method. +let original_method: DIDUrl = document.resolve_method(fragment_1.as_str(), None).unwrap().id().clone(); +document.purge_method(&storage, &original_method).await.unwrap(); +``` + + + + +```js +// Remove a verification method. +let originalMethod = document.resolveMethod(fragment) as VerificationMethod; +await document.purgeMethod(storage, originalMethod?.id()); +``` + + + + +This removes the original verification method with the fragment `key-1`. + +```json +{ + "doc": { + "id": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a", + "verificationMethod": [ + { + "id": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a#yJz-sPlCmd432JKqK_hkiPml2kj22Jv0aAFy_2jJ8nE", + "controller": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a", + "type": "JsonWebKey", + "publicKeyJwk": { + "kty": "OKP", + "alg": "EdDSA", + "kid": "yJz-sPlCmd432JKqK_hkiPml2kj22Jv0aAFy_2jJ8nE", + "crv": "Ed25519", + "x": "h8ndZ4_Urmzf4xN4emqS8r5q4pAQvAh0k2YHq5JLBBo" + } + } + ], + "authentication": [ + "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a#yJz-sPlCmd432JKqK_hkiPml2kj22Jv0aAFy_2jJ8nE" + ], + "service": [ + { + "id": "did:iota:tst:0x19ed80fbd2a644fc2347e27e46e09d42b89df9b1ba09ae41832a9d47d686776a#linked-domain", + "type": "LinkedDomains", + "serviceEndpoint": "https://iota.org/" + } + ] + }, + "meta": { + "created": "2023-11-16T20:40:03Z", + "updated": "2023-11-16T20:40:08Z", + "governorAddress": "tst1qrjsnlg6nqd2kdzx4q880nl74jtrcajm7ae57zazl0l7ye09ahh4x6z9gtd", + "stateControllerAddress": "tst1qrjsnlg6nqd2kdzx4q880nl74jtrcajm7ae57zazl0l7ye09ahh4x6z9gtd" + } +} +``` + +## Publish Your Updates + +Publish the updated DID Document inside the Alias Output taking into account the increase in the storage deposit needed. + + + + +```rust + // Resolve the latest output and update it with the given document. + let alias_output: AliasOutput = client.update_did_output(document.clone()).await?; + + // Because the size of the DID document increased, we have to increase the allocated storage deposit. + // This increases the deposit amount to the new minimum. + let rent_structure: RentStructure = client.get_rent_structure().await?; + let alias_output: AliasOutput = AliasOutputBuilder::from(&alias_output) + .with_minimum_storage_deposit(rent_structure) + .finish()?; + + // Publish the updated Alias Output. + let updated: IotaDocument = client.publish_did_output(&secret_manager, alias_output).await?; +``` + + + + +```js + // Resolve the latest output and update it with the given document. + let aliasOutput: AliasOutput = await didClient.updateDidOutput(document); + + // Because the size of the DID document increased, we have to increase the allocated storage deposit. + // This increases the deposit amount to the new minimum. + const rentStructure: IRent = await didClient.getRentStructure(); + + aliasOutput = await client.buildAliasOutput({ + ...aliasOutput, + amount: Utils.computeStorageDeposit(aliasOutput, rentStructure), + aliasId: aliasOutput.getAliasId(), + unlockConditions: aliasOutput.getUnlockConditions(), + }); + + // Publish the output. + const updated: IotaDocument = await didClient.publishDidOutput(secretManager, aliasOutput); +``` + + + + +## Full Example Code + + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/0_basic/1_update_did.rs +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/0_basic/1_update_did.ts +``` + + + \ No newline at end of file diff --git a/docs/content/guides/developer/iota-identity/how-tos/domain-linkage/create-and-verify.mdx b/docs/content/guides/developer/iota-identity/how-tos/domain-linkage/create-and-verify.mdx new file mode 100644 index 00000000000..ef3a313e224 --- /dev/null +++ b/docs/content/guides/developer/iota-identity/how-tos/domain-linkage/create-and-verify.mdx @@ -0,0 +1,179 @@ +--- +description: How to link a domain and a DID +sidebar_label: Create and Verify +image: /img/Identity_icon.png +tags: + - well-known + - domain linkage + - DID Configuration Resource + - Domain Linkage Credential +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Domain Linkage + +:::info +To use Domain Linkage in Rust you have to enable the `domain-linkage` feature. +::: + +## Overview + +Domain Linkage can provide proof for a connection between a DID and a domain being controlled by the same entity. +This linkage can transfer trust from a domain to a DID and vice versa. +For instance, if an entity trusts a domain, it can also trust the linked DID and all documents signed by +the verification methods included in the DID Document. + +A use case could be a verifier that trusts `www.example.com`, and receives a verifiable presentation issued by `did:foo:abc`. +If `did:foo:abc` is linked to `www.example.com`, the verifier can trust that the verifiable presentation is issued by +the same entity controlling `www.example.com`. +The DIF has approved a [Well Known DID Configuration](https://identity.foundation/.well-known/resources/did-configuration/) draft to standardize this connection by introducing +the [DID Configuration Resource](https://identity.foundation/.well-known/resources/did-configuration/#did-configuration-resource) and the [Linked Domain Service Endpoint](https://identity.foundation/.well-known/resources/did-configuration/#linked-domain-service-endpoint). + +![Identity getting started](/img/domain-linkage-diagram.png) + +### DID Configuration Resource + +Suppose that a DID `did:foo:example` with the following DID Document only contains one `verificationMethod`, `key-1`: + +```json {5} +{ + "id": "did:foo:abc", + "verificationMethod": [ + { + "id": "did:foo:abc#key-1", + "controller": "did:foo:abc", + "type": "Ed25519VerificationKey2018", + "publicKeyMultibase": "zDShpHKXkcHKHcF8CnGAA1UqyyuEPRNz1XFEuggbWJQSq" + } + ] + }, +``` + +The domain `https://www.example.com` represents the same entity and needs to be linked to increase trust in the DID. + +To establish this link, you must create a [DID Configuration Resource](https://identity.foundation/.well-known/resources/did-configuration/#did-configuration-resource), +and make it available on the [DID Configuration URL](https://identity.foundation/.well-known/resources/did-configuration/#did-configuration-uri). +In this case it's `https://example.com/.well-known/did-configuration.json`. + +The [DID Configuration Resource](https://identity.foundation/.well-known/resources/did-configuration/#did-configuration-resource) is a JSON-LD object containing verifiable credentials called `Domain Linkage Credentials`. +Each credential represents a linkage to a single DID. + +:::note + +Note that one `DID Configuration Resource` can include multiple `Domain Linkage Credentials`, +effectively linking the same domain to multiple DIDs. + +::: + +In this example, the domain `https://www.example.com` needs to be linked to the DID `did:foo:abc`. +This means that the `DID Configuration Resource` will have one `Domain Linkage Credential`. +This credential must have the following properties: + +- Its `type` includes `DomainLinkageCredential`. +- It includes the DID Configuration context. +- The `credentialSubject` must be the DID `did:foo:abc` and references the domain `https://www.example.com`. +- The issuer is the DID itself `did:foo:abc`. +- It is signed by a key material included in the DID Document, in this case `did:foo:abc#key-1`. + +```json +{ + "@context": "https://identity.foundation/.well-known/did-configuration/v1", + "linked_dids": [ + { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://identity.foundation/.well-known/did-configuration/v1" + ], + "type": ["VerifiableCredential", "DomainLinkageCredential"], + "credentialSubject": { + "id": "did:foo:abc", + "origin": "https://www.example.com/" + }, + "issuer": "did:foo:abc", + "issuanceDate": "2023-02-09T22:14:15Z", + "expirationDate": "2024-02-09T22:14:15Z", + "proof": { + "type": "JcsEd25519Signature2020", + "verificationMethod": "did:foo:abc#key-1", + "signatureValue": "4SvYqo3YoArfW7r7qKfN7RUJdZnBteb166KE4UkX8MNdbp5UW6YbykneAzvjyRmf5EVQ9bnP9cS5sbEPUn2uaAcB" + } + } + ] +} +``` + +Now this `DID Configuration Resource` must be made available on `https://example.com/.well-known/did-configuration.json`, +which establishes the linkage. + +### Linked Domain Service Endpoint + +By having a domain, one can discover what DIDs are linked to it by fetching the `DID Configuration Resource` and +investigating the `Domain Linkage Credentials`. + +If you want to enable discovery from the other direction, that is, if you have a DID and want to discover which +domains are linked to it, you can add a [Linked Domain Service Endpoint](https://identity.foundation/.well-known/resources/did-configuration/#linked-domain-service-endpoint) to the DID Document. +The DID Document from this example will be extended as follows to enable discovery of `https://www.example.com`: + +```json {11-17} +{ + "id": "did:foo:abc", + "verificationMethod": [ + { + "id": "did:foo:abc#key-1", + "controller": "did:foo:abc", + "type": "Ed25519VerificationKey2018", + "publicKeyMultibase": "zDShpHKXkcHKHcF8CnGAA1UqyyuEPRNz1XFEuggbWJQSq" + } + ], + "service": [ + { + "id": "did:foo:abc#domain-linkage", + "type": "LinkedDomains", + "serviceEndpoint": "https://www.example.com/" + } + ] +} +``` + +:::note +Note that a DID Document can have multiple `Linked Domain Services` and each service can link to multiple domains. +::: + +### Verifying a DID and Domain Linkage + +As mentioned above, you can discover the Domain Linkage from either direction. +However, verifying the linkage in both cases involves only verifying the DID Configuration Resource. +The process is as follows: + +1. Fetch `DID Configuration Resource` from `https://www.example.com/.well-known/did-configuration.json`. +2. Resolve the DID Document of `did:foo:abc`. +3. Verify the `DID Configuration Resource` and its `Domain Linkage Credential` that references `did:foo:abc`. + + +:::tip About DID Configuration Resource Verification + +You can learn more +[about DID Configuration Resource Verification on the Identity Foundation website](https://identity.foundation/.well-known/resources/did-configuration/#did-configuration-resource-verification). + +::: + +## Example Code + + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/1_advanced/6_domain_linkage.rs +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/1_advanced/5_domain_linkage.ts +``` + + + diff --git a/docs/content/guides/developer/iota-identity/how-tos/key-storage.mdx b/docs/content/guides/developer/iota-identity/how-tos/key-storage.mdx new file mode 100644 index 00000000000..5d76d6dcaa9 --- /dev/null +++ b/docs/content/guides/developer/iota-identity/how-tos/key-storage.mdx @@ -0,0 +1,152 @@ +--- +title: Key Storage +sidebar_label: Key Storage +description: Explain the use of the storage interfaces and how they can be implemented +image: /img/Identity_icon.png +tags: + - key storage + - storage interfaces + - json web key + - json web algorithm + - signing +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +## Introduction + +The `JwkDocumentExt` API allows you to modify a DID document, for example, adding new verification methods. +It enables storing the secrets that verification methods represent securely. +It does so using the two storage interfaces, the `JwkStorage` and `KeyIdStorage`. +We refer to both of these as the **key storage**. + +The main idea behind the key storage is strongly inspired by the architecture of key management systems (KMS) +or secure enclaves: once private keys are entered into the system, they can never be retrieved again. +Instead, all operations using the key will have to go through that system. + +This approach allows the key storage to be architected more securely than simply storing and loading private keys from +a regular database. +Of course, security is directly dependent on the concrete implementation, +which is why we provide [Stronghold](https://github.com/iotaledger/stronghold.rs/), a best-effort in-software enclave, by default. + +However, there are cases where one cannot use `Stronghold`, +or may want to integrate key management of identities into their own KMS or similar, +which is why the key storage is an abstraction over such systems. +Any implementation of a key storage can be used by the `JwkDocumentExt` API. + +The two interfaces making up the key storage have two respective responsibilities. + +:::info + +Even though there are two separate interfaces, you can implement them using the same backing storage. + +::: + +## Function Overview + +A brief overview of those functions: + +- `JwkStorage`: CRUD and signing operations on [JSON Web Keys](https://www.rfc-editor.org/rfc/rfc7517). + - `generate`: Generate a new key represented as a JSON Web Key. + - `insert`: Insert an existing JSON Web Key into the storage. + - `sign`: Signs the provided data using the stored private key. + - `delete`: Permanently deletes a key. + - `exists`: Returns whether a key exists. +- `KeyIdStorage`: Stores the mappings from verification methods to their corresponding key identifier in the `JwkStorage`. + - `insert_key_id`: Inserts a mapping from a verification method identifier to a key identifier. + - `get_key_id`: Returns the key identifier for a given verification method identifier. + - `delete_key_id`: Deletes a mapping. + +## Key Identifier + +A `JwkStorage` stores and operates on keys, so they must be identified. +In general, Key Management Systems use some form of an identifier for their keys. +To abstract over those, the `JwkStorage` interface has a general-purpose `KeyId` type, +which is effectively a wrapper around a string. + +A `KeyIdStorage` is needed to store the key id that represents the private key for a given verification method. +To that end, a verification method itself must be identified. + +While within a document, each fragment must be unique, the same is not true given multiple documents, +so we cannot rely only on fragments if we don't want to partition the `KeyIdStorage` by DID. +The solution to this is using a `MethodDigest`, a hash over a verification method. + +When following best security practices, each verification method has its own associated key and, thus, a unique public key. +That, plus the fragment of a method, ensures the `MethodDigest` is unique. + +So, in essence, a `JwkStorage` stores a `KeyId -> JWK` mapping while a `KeyIdStorage` stores a `MethodDigest -> KeyId` mapping. + +:::caution + +Given the construction and limitations of the method digest, +no two documents should contain a method that shares both the same fragment and public key. +This should not happen under typical circumstances, but it is good to keep it in mind. + +::: + +## Key Types + +To express what key types a given `JwkStorage` implementation supports, you should use the `KeyType`, +which is another simple wrapper around a string. + +The reason for this design might seem odd in Rust, given the existence of associated types. +This more simplistic design is necessary to accommodate implementing the interface via the bindings to the library. + +Implementations are expected to export constants of the key types they support, +so users have an easy way to discover the supported types. +In general, storage implementations are free to support any [JSON Web Algorithm](https://www.rfc-editor.org/rfc/rfc7518.html)-compatible key. +However, the recommended default used by IOTA Identity is the `EdDSA` algorithm with curve `Ed25519`. + +## Implementation + +The IOTA Identity library ships two implementations of key storage. +The `JwkMemStore` and `KeyIdMemstore` are insecure in-memory implementations +intended as example implementations and for testing. + +The default key storage implementation is `Stronghold`, +which is an example of a storage that implements both storage interfaces simultaneously. +[`Stronghold`](https://github.com/iotaledger/stronghold.rs/) may be interesting for implementers to look at, +as it needs to deal with some challenges the in-memory version does not have to deal with. Note that the `Stronghold` implementation is only available in Rust. + +## Examples + +This section shows the Rust and TypeScript `Memstore` implementations. + +### `JwkMemStore` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/lib/jwk_storage.ts +``` + + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/identity_storage/src/key_storage/memstore.rs +``` + + + + +### `KeyIdMemstore` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/lib/key_id_storage.ts +``` + + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/identity_storage/src/key_id_storage/memstore.rs +``` + + + diff --git a/docs/content/guides/developer/iota-identity/how-tos/verifiable-credentials/create.mdx b/docs/content/guides/developer/iota-identity/how-tos/verifiable-credentials/create.mdx new file mode 100644 index 00000000000..4598ecac57b --- /dev/null +++ b/docs/content/guides/developer/iota-identity/how-tos/verifiable-credentials/create.mdx @@ -0,0 +1,141 @@ +--- +title: Create a Verifiable Credential +sidebar_label: Create and Sign +description: Explain how a VC is created and verified +image: /img/Identity_icon.png +tags: + - verifiable + - credentials + - Create + - sign +--- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +A [Verifiable Credential (VC)](./../../explanations/verifiable-credentials.mdx) can represent all +information that a physical credential represents, such as a passport or university +degree. However, by allowing other parties to cryptographically verify the authorship +and integrity of the claims, verifiable credentials can be seen as more tamper-evident +and more trustworthy than their physical counterparts. + +## Verifiable Credential Properties + +In the IOTA Identity Framework, you can create a Verifiable Credential with the following properties: + +- [**Context**](https://www.w3.org/TR/vc-data-model/#contexts): List of JSON-LD context URIs. Includes `"https://www.w3.org/2018/credentials/v1"` by default. +- [**Types**](https://www.w3.org/TR/vc-data-model/#types): List of types describing the credential. Includes `"VerifiableCredential"` by default. +- [**Subject**](https://www.w3.org/TR/vc-data-model/#credential-subject): The issuer's claims; a set of objects that contain one or more properties that are each related to a subject. +- [**Issuer**](https://www.w3.org/TR/vc-data-model/#issuer): The identifier of the issuer, typically their [DID](../../explanations/decentralized-identifiers.mdx). +- [**ID**](https://www.w3.org/TR/vc-data-model/#identifiers): Optional URI identifier for the credential. +- [**Issuance Date**](https://www.w3.org/TR/vc-data-model/#issuance-date): Timestamp for expressing the date and time when a credential becomes valid. +- [**Expiration Date**](https://www.w3.org/TR/vc-data-model/#expiration): Optional timestamp for expressing the date and time when a credential ceases to be valid. +- [**Status**](https://www.w3.org/TR/vc-data-model/#status): Optional information used to determine the current status of a credential, i.e. whether or not it has been [revoked](./revocation.mdx). +- [**Schema**](https://www.w3.org/TR/vc-data-model/#data-schemas): Optional list of objects specifying the schema that the data must conform to. +- [**Refresh Service**](https://www.w3.org/TR/vc-data-model/#refreshing): Optional link to a service where the recipient may refresh the included credentials. +- [**Terms of Use**](https://www.w3.org/TR/vc-data-model/#terms-of-use): Optional list of policies defining obligations, prohibitions, or permissions of the presentation recipient. +- [**Evidence**](https://www.w3.org/TR/vc-data-model/#evidence): Optional list of objects that can be used by the issuer to provide the verifier with additional supporting information in a verifiable credential. +- [**Non-Transferable**](https://www.w3.org/TR/vc-data-model/#nontransferable-property): Optional flag that indicates that a verifiable credential must only be encapsulated in a [verifiable presentation](./../../explanations/verifiable-presentations.mdx) whose proof was issued by the credential subject. + + + + +## Signing {#signing} + +After preparing the verifiable credential, the issuer creates a signed JWT containing VC in the claims using one of their private keys. This is what allows verifiers to validate the credential independently using the corresponding public key from the issuer's DID Document. + +## Validation + +Verifiers should ensure certain credential properties are valid when receiving one or more in a [verifiable presentation](./../../explanations/verifiable-presentations.mdx). Both issuers and holders may also wish to validate their credentials, particularly directly after creating or receiving one. Validation may be performed at any point in time and can be a useful way of checking whether a credential has expired or been revoked. + +### Validation Checks + +The IOTA Identity Framework supports the following checks during credential validation: + +- **Semantic structure**: Ensures the credential adheres to the specification. +- **Signature**: Verifies the JWS against the issuer's DID Document. +- **Optional validations**: Additional checks on credential properties, and the signature can be configured by specifying [Validation Options](#validation-options). + +### Validation Options + +These options specify conditions that specific properties in a credential must satisfy. + +- **Expiration Date**: Check that the [`expirationDate`](https://www.w3.org/TR/vc-data-model/#expiration) property, if present, is not before a specific date-time. Defaults to the current datetime if unset. +- **Issuance Date**: Check that [`issuanceDate`](https://www.w3.org/TR/vc-data-model/#issuance-date) property, if present, is not after a specific date-time. Defaults to the current datetime if unset. +- **Verifier Options**: Validates aspects of the credential signature. + +## Sharing Verifiable Credentials + +A [verifiable presentation](./../../explanations/verifiable-presentations.mdx) is the recommended data format for sharing one or more verifiable credentials, +as it provides cryptographic means of proving the DID of the holder presenting them, +and for enforcing [subject-holder relationships](https://www.w3.org/TR/vc-data-model/#subject-holder-relationships). + +## Example + +The following code showcases how an issuer can [create, sign](#create-and-sign-vc), +and [validate](#validate-a-vc) a verifiable credential. +In this example, the issuer signs a `UniversityDegreeCredential` with Alice's name and DID. + +### Create and Sign a VC + + +
+ + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/0_basic/5_create_vc.rs#L67-L98 +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/0_basic/5_create_vc.ts#L51-L74 +``` + + + +
+ +### Validate a VC + +
+ + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/0_basic/5_create_vc.rs#L105-L113 +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/0_basic/5_create_vc.ts#L83-L88 +``` + + + +
+ +This Verifiable Credential can be [verified by anyone](./../../explanations/verifiable-presentations.mdx), +allowing Alice to take control of it and share it with anyone. + +### Full Example Code + + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/0_basic/5_create_vc.rs +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/0_basic/5_create_vc.ts +``` + + + diff --git a/docs/content/guides/developer/iota-identity/how-tos/verifiable-credentials/revocation.mdx b/docs/content/guides/developer/iota-identity/how-tos/verifiable-credentials/revocation.mdx new file mode 100644 index 00000000000..2e7c35e497d --- /dev/null +++ b/docs/content/guides/developer/iota-identity/how-tos/verifiable-credentials/revocation.mdx @@ -0,0 +1,208 @@ +--- +sidebar_label: Revoke +description: Explain how a VC can be revoked +image: /img/Identity_icon.png +tags: + - verifiable + - credentials + - revoke + - revocation +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Revoke a Verifiable Credential + +The [example](#example) below demonstrates two methods that an issuer can use to revoke a verifiable credential +using the IOTA Identity Framework: + +1. By using the [`credentialStatus`](https://www.w3.org/TR/vc-data-model/#status) field in a credential and linking +to a [revocation method](#revocation-methods). +2. By [removing the verification method](#removing-the-verification-method) that signed the credential. +This invalidates all credentials that were signed with that verification method. + +## Revocation methods +The IOTA Identity Framework supports two different revocation methods: `RevocationBitmap2022` and `StatusList2021`. +### Revocation Bitmap +[RevocationBitmap2022](../../references/specifications/revocation-bitmap-2022.mdx) is the default credential revocation method used in the IOTA Identity Framework. It allows +issuers to control whether a credential is _valid_ or _revoked_. To do so, a revocation list (represented +as a bitmap) is stored in the issuer's DID document. +When a credential is issued, a unique index from the issuer's revocation list +is chosen, linking the credential's status to the value of the list entry. To change the status of a credential, the issuer +simply updates the corresponding entry in its revocation list. + +With `RevocationBitmap2022` the `identity.rs` library completely handles the processes required to handle credentials revocation; +from creation and storage of the revocation list to its lookup. +This makes `RevocationBitmap2022` the preferred way for users to handle credential revocation, but it requires sufficient +funds to rent out the required on-tangle space. + +:::note + +DLT's size constraints limit the size of the revocation list. With the assumption of only one such revocation list +per the issuer's DID document, one may expect to be able to handle roughly 50k entries. + +::: + + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/0_basic/7_revoke_vc.rs#L167 +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/0_basic/7_revoke_vc.ts#L156 +``` + + + + +If the binary value of the index in the bitmap is 1 (one), the verifiable credential is revoked, +if it is 0 (zero) it is not revoked. + +For example, with this approach the issuer adds an index to a credential in the `credentialStatus` field, such as `"5"`. +This part of the credential might then look like this: + +```json +"credentialStatus": { + "id": "did:iota:EvaQhPXXsJsGgxSXGhZGMCvTt63KuAFtaGThx6a5nSpw#revocation", + "type": "RevocationBitmap2022", + "revocationBitmapIndex": "5" +}, +``` + +The verifier uses the `id` field (`did:iota:EvaQhPXXsJsGgxSXGhZGMCvTt63KuAFtaGThx6a5nSpw#revocation`) to look up the +service in the issuer's DID document: + +```json +{ + "id": "did:iota:EvaQhPXXsJsGgxSXGhZGMCvTt63KuAFtaGThx6a5nSpw#revocation", + "type": "RevocationBitmap2022", + "serviceEndpoint": "data:application/octet-stream;base64,ZUp5ek1tQmdZR1NBQUFFZ1ptVUFBQWZPQUlF" +} +``` + +During verification, the verifier decodes the revocation bitmap embedded in the `data` URL. +This bitmap written as a bitstring looks like this: `000001`. +Here, the 5th bit is set, which means the credential with that index is revoked, +while all other credentials aren't revoked. + +### StatusList2021 +[StatusList2021](https://www.w3.org/TR/2023/WD-vc-status-list-20230427) offers similar functionalities to `RevocationBitmap2022` +but in a more flexible and scalable way. +The main difference is that `StatusList2021` is completely agnostic in regards to how the issuer's status list +is stored and fetched, as long as its location can be encoded through a URL. For instance, the status list +can be made available over HTTP (e.g. `https://example.com/credentials/status`) or through the +Interplanetary File System (e.g. `ipfs://QmXDWGdVBhbDoXXzKNMhJk5ejnZgxpMBVzW4EhQaHPD3Mi`). + +This flexibility, although it requires the issuer to manually fetch and update its status list, allows for an arbitrary number of +entries in the status list, in contrast with `RevocationBitmap2022`, where the length of the list is limited by the DLT's constraints. + +Furthermore, `StatusList2021` introduces a new credential state: _suspended_. Suspended credentials are credentials that a validator will not accept as _valid_, but that might become valid again in the future. Instead, _revoked_ credentials **cannot** ever +be valid again, as the _revoked_ state is irreversible. + + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/1_advanced/8_status_list_2021.rs#L86-L90 +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/1_advanced/7_status_list_2021.ts#L72-L76 +``` + + + + +First, an issuer creates a credential that encodes a certain status list, specifying its purpose (either `revocation` or `suspension`) +and the location at which it will be available (`https://example.com/credentials/status` in this case). After creation, the issuer +must make the credential available at the chosen URL so that verifiers can fetch it. + +Upon issuing a credential, to revoke it or suspend it later, the issuer sets the `credentialStatus` field, linking +to an entry in its status list. The snippet below shows what `credentialStatus` would look like when linking to the previously created +status list credential. + +```json +{ + "id": "https://example.com/credentials/status#94567", + "type": "StatusList2021Entry", + "statusPurpose": "revocation", + "statusListIndex": "94567", + "statusListCredential": "https://example.com/credentials/status" +} +``` + + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/1_advanced/8_status_list_2021.rs#L173 +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/1_advanced/7_status_list_2021.ts#L147 +``` + + + + +To set the status of a credential, the issuer retrieves the status list credential and sets the value of the chosen entry index. + +## Removing the Verification Method + +A less efficient alternative is to remove the verification method that signed the credential from the DID Document of +the issuer. +This means the VC can no longer be validated. + +However, this will also invalidate every VC signed with that verification method, +meaning that the issuer will have to sign every VC with a different key to retain +precise control over which credential is revoked. + + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/0_basic/7_revoke_vc.rs#L197-L204 +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/0_basic/7_revoke_vc.ts#L192C1-L195 +``` + + + + +## Full Example Code + +The following code exemplifies how you can revoke a [Verifiable Credential (VC)](../../explanations/verifiable-credentials.mdx). + + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/0_basic/7_revoke_vc.rs +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/0_basic/7_revoke_vc.ts +``` + + + diff --git a/docs/content/guides/developer/iota-identity/how-tos/verifiable-credentials/selective-disclosure.mdx b/docs/content/guides/developer/iota-identity/how-tos/verifiable-credentials/selective-disclosure.mdx new file mode 100644 index 00000000000..7b816429c09 --- /dev/null +++ b/docs/content/guides/developer/iota-identity/how-tos/verifiable-credentials/selective-disclosure.mdx @@ -0,0 +1,141 @@ +--- +sidebar_label: Selective Disclosure +description: Explain VC with selective disclosure. +image: /img/Identity_icon.png +tags: + - verifiable + - credentials + - SD-JWT + - Disclosure +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Selective Disclosure (SD-JWT) + + +Holders of verifiable credentials may prefer to keep all the information contained within the credential private from a verifier. Instead, they may opt only to share a specific subset of the properties included in the VC. The identity library implements the [IETF Specifications](https://www.ietf.org/archive/id/draft-ietf-oauth-selective-disclosure-jwt-07.html), which outlines a mechanism to enable the selective disclosure of individual properties within the JSON object of JWT claims. + +## Concept + +### Issuance + +During the issuance process, the issuer replaces a subset of the fields in a credential with digests of their salted values and creates a signed JWT. Next, JWT, alongside the plain text disclosures and the salt used for digest creation are sent to the holder. + +### Presentation + +At this stage, the holder can selectively choose which fields to disclose to the verifier. The disclosures are sent in plain text, with the JWT containing the digests to the verifier. + +:::note +Only values replaced by digests through the issuer can be selectively disclosed. The holder **can not** conceal values provided in plain text in the JWT claims. +::: + + +### Validation + +With these values and a valid signature, the verifier is able to reconstruct a Verified Credential (VC) that exclusively contains the information the holder intended to disclose. + +## How It Works + +A SD JWT can be constructed from the following JWT claim of an address credential in accordance with the [VC Data Model v1.1](https://www.w3.org/TR/vc-data-model/#json-web-token): + + +```json +{ + "iss": "did:iota:tst:0x899d07a766f93c2af1a19a3f4583ad338fc94c5d84b6afcadf49b197e1cb693e", + "jti": "https://example.com/credentials/3732", + "nbf": 1705925652, + "sub": "did:iota:tst:0x6c045e1f658197b432cfc7c66350b8781dca50f820e9de0fcdf0029b4b384355", + "vc": { + "@context": "https://www.w3.org/2018/credentials/v1", + "credentialSubject": { + "address": { + "country": "DE", + "locality": "Maxstadt", + "postal_code": "12344", + "street_address": "Weidenstraße 22" + }, + "name": "Alice" + }, + "type": [ + "VerifiableCredential", + "AddressCredential" + ] + } +} + +``` + +The issuer makes the values of "locality", "postal_code", and "street_address" selectively disclosable, giving the holder the freedom to select what details of the address to be disclosed and presented. + +```json +{ + "_sd_alg": "sha-256", + "iss": "did:iota:tst:0x899d07a766f93c2af1a19a3f4583ad338fc94c5d84b6afcadf49b197e1cb693e", + "jti": "https://example.com/credentials/3732", + "nbf": 1705925652, + "sub": "did:iota:tst:0x6c045e1f658197b432cfc7c66350b8781dca50f820e9de0fcdf0029b4b384355", + "vc": { + "@context": "https://www.w3.org/2018/credentials/v1", + "credentialSubject": { + "address": { + "_sd": [ + "8Dai0-GMZgkzmdryGzjYufUaRFkiNWzVsJJdWucwu84", + "jemTNaG_wiHauwmwWiWREsirAlr91qugPds4MA8e2xo", + "iakC9Dfe2r9fGnOaAr_pGg1b7CwITBjcwE7-O7WlMnY" + ], + "country": "DE" + }, + "name": "Alice" + }, + "type": [ + "VerifiableCredential", + "AddressCredential" + ] + } +} +``` + +:::note +The digests are contained in the `_sd` property in `address`. This allows both keys and values to be concealed. +::: + +For further details, see the [example](#full-example-code) below and the [sd-jwt-payload crate](https://github.com/iotaledger/sd-jwt-payload). + +## Presentation format + +The SD-JWT is presented in the following [format](https://www.ietf.org/archive/id/draft-ietf-oauth-selective-disclosure-jwt-07.html#section-5): + +> `~~~...~~` + +## Key Binding JWT + +When a verifier receives an SD-JWT, it may be desirable to verify that the presenter's identity matches the holder of the Credential. For that purpose, a [Key Binding JWT (KB-JWT)](https://www.ietf.org/archive/id/draft-ietf-oauth-selective-disclosure-jwt-07.html#section-4.3) can be used. + + +- The verifier sends a nonce to the holder. +- The holder creates a JWT containing the nonce and the digest of the issuer-signed JWT and the disclosures 1→N. +- The holder sends the KB-JWT to the verifier as a part of the presentation. +- By verifying the KB-JWT, the verifier ensures the identity of the holder, the integrity of the data, the freshness of the signature, and the intended audience. + + + +## Full Example Code + + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/1_advanced/7_sd_jwt.rs +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/1_advanced/6_sd_jwt.ts +``` + + + diff --git a/docs/content/guides/developer/iota-identity/how-tos/verifiable-credentials/zero-knowledge-selective-disclosure.mdx b/docs/content/guides/developer/iota-identity/how-tos/verifiable-credentials/zero-knowledge-selective-disclosure.mdx new file mode 100644 index 00000000000..e11ad510239 --- /dev/null +++ b/docs/content/guides/developer/iota-identity/how-tos/verifiable-credentials/zero-knowledge-selective-disclosure.mdx @@ -0,0 +1,151 @@ +--- +sidebar_label: Zero Knowledge Selective Disclosure +description: Zero Knowledge selectively disclosable VCs. +image: /img/Identity_icon.png +tags: + - verifiable + - credentials + - Zero Knowledge + - Disclosure +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Zero Knowledge Selective Disclosure (ZK-SD-VCs) +ZK-SD-VCs allow holders to verify their VCs without having to disclose the entire VC's claim set to verifiers. +This is done through the creation of a Zero Knowledge Proof (ZKP) that guarantees the integrity and authenticity +of the VC, even when only partially disclosed to the verifier. + +:::note +Although ZK-SD-VCs offer similar functionalities to [SD-JWT VCs](../selective-disclosure) - at least on a high level - they rely on completely different +concepts and security concerns. For a user, the most notable difference is the shifted capability of choosing which fields can +be concealed from a verifier. For ZK-SD-VCs it's the holder that has total control over which parts of the credential can be +undisclosed, whereas for SD-JWT VCs it's the issuer that decides which fields may be concealed by the holder. +::: + +## Concepts +### Issuance +The issuer of a ZK-SD-VC creates the credential, signs it using the [BBS+](https://www.ietf.org/archive/id/draft-irtf-cfrg-bbs-signatures-05.html) signature scheme +and sends both the credential and the signature to the holder. To facilitate this process, the credential is first encoded +as a [JSON Proof Token](https://www.ietf.org/archive/id/draft-ietf-jose-json-proof-token-02.html) (JPT), which is then used as the payload of a +[JSON Web Proof](https://www.ietf.org/archive/id/draft-ietf-jose-json-web-proof-02.html) (JWP) and sent to the holder as JPT. +:::note +JWPs and JPTs can be reasoned about as the Zero Knowledge (ZK) based counterparts of JWSs and JWTs. +::: +In code, this process would look like the following snippet: + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/1_advanced/9_zkp.rs#L114-L141 +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/1_advanced/8_zkp.ts#L109-L133 +``` + + + + + +Note how the VC issuer makes no prescription whatsoever regarding the disclosability of the VC's fields. + +### Holder presentation + +Once the holder receives a presentation challenge from a verifier, they construct a selective disclosure presentation for the requested credential +and send it back for verification. For this process the JWP in possession of the holder undergoes a transformation that allows the holder +to conceal any fields from the credentials claims through the creation of a Zero Knowledge Proof (ZKP) of the issuer's signature and becomes a _presented JWP_. +The proof value depends on the selected [JSON Proof Algorithm](https://www.ietf.org/archive/id/draft-ietf-jose-json-proof-algorithms-02.html) (JPA). + + + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/1_advanced/9_zkp.rs#L197-L223 +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/1_advanced/8_zkp.ts#L178-L199 +``` + + + + +Here's an example presented JWP in its JPT JSON serialization format where the undisclosed values are replaced by `null`: +``` +{ + "payloads": [ + null, + "IkpheSI", + null, + "NDI" + ], + "issuer": "eyJpc3MiOiJodHRwczovL2lzc3Vlci50bGQiLCJjbGFpbXMiOlsiZmFt + aWx5X25hbWUiLCJnaXZlbl9uYW1lIiwiZW1haWwiLCJhZ2UiXSwidHlwIjoiSlBUIiw + icHJvb2ZfandrIjp7ImNydiI6IlAtMjU2Iiwia3R5IjoiRUMiLCJ4IjoiYWNiSVFpdU + 1zM2k4X3VzekVqSjJ0cFR0Uk00RVUzeXo5MVBINkNkSDJWMCIsInkiOiJfS2N5TGo5d + ldNcHRubUt0bTQ2R3FEejh3Zjc0STVMS2dybDJHekgzblNFIn0sInByZXNlbnRhdGlv + bl9qd2siOnsiY3J2IjoiUC0yNTYiLCJrdHkiOiJFQyIsIngiOiJvQjFUUHJFX1FKSUw + 2MWZVT09LNURwS2dkOGoyemJaSnRxcElMRFRKWDZJIiwieSI6IjNKcW5ya3VjTG9ia2 + RSdU9xWlhPUDlNTWxiRnllbkZPTHlHbEctRlBBQ00ifSwiYWxnIjoiU1UtRVMyNTYif + Q", + "proof": "LJMiN6caEqShMJ5jPNts8OescqNq5vKSqkfAdSuGJA1GyJyyrfjkpAG0c + DJKZoUgomHu5MzYhTUsa0YRXVBnMB91RjonrnWVsakfXtfm2h7gHxA_8G1wkB09x09k + on2eK9gTv4iKw4GP6Rh02PEIAVAvnhtuiShMnPqVw1tCBdhweWzjyxJbG86J7Y8MDt2 + H9f5hhHIwmSLwXYzCbD37WmvUEQ2_6whgAYB5ugSQN3BjXEviCA__VX3lbhH1RVc27E + YkRHdRgGQwWNtuExKz7OmwH8oWizplEtjWJ5WIlJpee79gQ9HTa2QIOT9bUDvjjkkO- + jK_zuDjZwh5MkrcaQ", + "presentation": "eyJub25jZSI6InVURUIzNzFsMXB6V0psN2FmQjB3aTBIV1VOaz + FMZS1iQ29tRkx4YThLLXMifQ" +} +``` + +### Verification + +The verifier decodes the received JPT presentation and asserts the validity of the ZKP it contains, thus proving the +authenticity and integrity of the presented credential, without knowledge of any of the undisclosed fields and of the issuer signature. + + + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/1_advanced/9_zkp.rs#L244-L257 +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/1_advanced/8_zkp.ts#L217-L225 +``` + + + + +## Full Example Code + + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/1_advanced/9_zkp.rs +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/1_advanced/8_zkp.ts +``` + + + diff --git a/docs/content/guides/developer/iota-identity/how-tos/verifiable-presentations/create-and-validate.mdx b/docs/content/guides/developer/iota-identity/how-tos/verifiable-presentations/create-and-validate.mdx new file mode 100644 index 00000000000..4bf74231f28 --- /dev/null +++ b/docs/content/guides/developer/iota-identity/how-tos/verifiable-presentations/create-and-validate.mdx @@ -0,0 +1,116 @@ +--- +sidebar_label: Create and Validate +description: Explain how a VP is created and verified +image: /img/Identity_icon.png +tags: + - verifiable + - presentations +--- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Create and Validate Verifiable Presentations + +The IOTA Identity Framework enables holders to easily construct +[verifiable presentations](./../../explanations/verifiable-presentations.mdx). +As demonstrated in the [example](#example-code), +holders only need to pass in their credentials to create a JWT presentation. + +## Properties + +You can specify the following properties in a presentation: + +- [**ID**](https://www.w3.org/TR/vc-data-model/#identifiers): Optional URI identifier for the presentation. +- [**Context**](https://www.w3.org/TR/vc-data-model/#contexts): List of JSON-LD context URIs. Includes `"https://www.w3.org/2018/credentials/v1"` by default. +- [**Types**](https://www.w3.org/TR/vc-data-model/#types): List of types describing the presentation. Includes `"VerifiablePresentation"` by default. +- [**Credentials**](https://www.w3.org/TR/vc-data-model/#dfn-verifiable-credentials): List of verifiable credentials to present. +- [**Holder**](https://www.w3.org/TR/vc-data-model/#dfn-holders): Optional URI, typically a DID, of the entity that generated the presentation. +- [**Refresh Service**](https://www.w3.org/TR/vc-data-model/#refreshing): Optional link to a service where the recipient may refresh the included credentials. +- [**Terms of Use**](https://www.w3.org/TR/vc-data-model/#terms-of-use): Optional list of policies defining obligations, prohibitions, or permissions of the presentation recipient. + +Of the above, **only the list of credentials is required** when creating a presentation using the framework. +However, the holder property should be included to satisfy [subject-holder relationship](#subject-holder-relationship) checks during validation. + +After creation, the holder signs the verifiable presentation using a private key linked to one of the verification +methods in their DID Document and transmits it to a verifier for validation. + +## Creation and Validation + +A Verifiable Presentation can be issued as a JWT that provides data integrity, +and also proves the [DID](../../explanations/decentralized-identifiers.mdx) of the holder. + +:::note + +Verifiers should always send a challenge +to [mitigate replay attacks](./../../explanations/verifiable-presentations.mdx#security-considerations). +::: + + +The IOTA Identity Framework provides several options for verifiers to validate various sections of a verifiable presentation. +See the [example](#example-code) for a demonstration of how to validate a presentation. + +The framework checks: + +- **Semantic structure**: Ensures the presentation and its credentials adhere to the specification. +- **Presentation proof**: Verifies the presentation signature against the holder's DID document. +- **Credential proofs**: Verifies the credential signatures against the DID Documents of their respective issuers. + + +Currently, the following are **not** checked automatically: + +- **Data schemas**: Credentials that specify a [schema](https://www.w3.org/TR/vc-data-model/#data-schemas) property +should be examined to ensure conformance. +- **Fitness for purpose**: Whether the credentials in a presentation and the data within them are acceptable and +valid depends on the context in which they are used. Verifiers should ensure that the credential types, subjects, +and schemas sent by a holder match what was requested. +- **Issuer trustworthiness**: Verifiers must check that they trust the issuer on each individual credential in a +presentation. The framework only verifies that the issuer's signature on each credential is current and valid +against the given options. + +The default validation behavior may be modified by the following options. + +## Subject-Holder Relationship + +Specifies the expected relationship between the holder that signed the verifiable presentation and the subject +specified in each [verifiable credential](./../../explanations/verifiable-credentials.mdx). +This can be restricted by the [`nonTransferable`](https://www.w3.org/TR/vc-data-model/#nontransferable-property) property, +which indicates that a verifiable credential must only be encapsulated into a verifiable presentation whose holder matches the credential subject. + +By default, the framework always enforces that the holder matches the subject. + +The following options are available to modify that behavior: + +- **`AlwaysSubject` (default)**: The holder DID that signed the presentation must match the [`credentialSubject` `id`](https://www.w3.org/TR/vc-data-model/#credential-subject) field in each of the attached credentials. This is the safest option which ensures holders may only present credentials that were directly issued to their DID. An error is thrown on a mismatch or if no subject `id` is present. +- **`SubjectOnNonTransferable`**: The holder DID must match the subject only for credentials where the [`nonTransferable`](https://www.w3.org/TR/vc-data-model/#nontransferable-property) property is `true`. This is appropriate for accepting [bearer credentials](https://www.w3.org/TR/vc-data-model/#bearer-credentials) while still adhering to the specification. +- **`Any`**: The holder DID is not required to have any kind of relationship to any credential subject. This option performs no checks and ignores the [`nonTransferable`](https://www.w3.org/TR/vc-data-model/#nontransferable-property) property. + +:::note + +See the [Verifiable Credentials Data Model Specification](https://www.w3.org/TR/vc-data-model/#subject-holder-relationships) +for further discussion on the different subject-holder relationships. + +::: + + +## Example Code + +The following code demonstrates how to use the IOTA Identity Framework end-to-end to create and sign a verifiable +presentation as a holder, serialize it to JSON for transmission, deserialize it on the receiving side as a verifier, +and finally validate it with various options. + + + + +```rust reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/examples/0_basic/6_create_vp.rs +``` + + + + +```ts reference +https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src/0_basic/6_create_vp.ts +``` + + + diff --git a/docs/content/guides/developer/iota-identity/welcome.mdx b/docs/content/guides/developer/iota-identity/welcome.mdx new file mode 100644 index 00000000000..29910d80cb0 --- /dev/null +++ b/docs/content/guides/developer/iota-identity/welcome.mdx @@ -0,0 +1,91 @@ +--- +description: The most important concepts that developers will need to know to utilize IOTA Identity to its full potential. +image: /img/Identity_icon.png +tags: + - Identity + - guide + - TOC + - overview + - reference +--- +# IOTA Identity Framework + +![IOTA Identity](/img/banner/banner_identity.svg) + +The IOTA Identity framework implements the most common standards and patterns for Decentralized Identity in both a DLT agnostic and `iota` method-specific manner. +It is designed to work for Identity for [People](#identity-for-people), [Organizations](#identity-for-organizations), +[Things, and Objects](#identity-for-things) acting as a unifying layer of trust between everyone and everything. + +## Introduction to Decentralized Identity + +Decentralized or Self-Sovereign Identity (SSI) gives individuals full control over their online identity, +offering a remedy for database breaches, lack of digital trust, and stringent privacy laws like GDPR. +Digital identity bridges the gap between online pseudonyms and real-world personas, enabling true verifiable identities. This gives individuals the power to choose which data to share and with whom. + + + +### Identity for People + +:::info Privacy + +IOTA Identity builds a new internet, without usernames, passwords, endless repeated forums, or uncontrolled data harvesting. + +::: + +Information about anyone's life is spread across many locations. Most people have numerous unorganized important documents at home, hundreds of online accounts, and many more online footprints. Through statistical predictive analysis, computer programs can harvest unverified online information sources and create a reasonably accurate profile about our lives. These profiles are accurate enough for targeted advertising and personalized content but lack the proof and trust for them to be used in business. This results in an antiquated customer experience where we have to submit our age and address for every purchase we make and every account we create. It also inhibits our ability to do many online tasks like requesting and extending licenses or taking out a mortgage. + +Self-Sovereign Identity is about returning autonomy and privacy to the individual, while also improving our online experience. Some movements focus on data privacy, preventing companies from using our information altogether, but with the IOTA Identity framework you control which part of the information you want to reveal. The user can create a single online profile containing all our personal information. They can decide who they share what information with, and a verifier checks if the information is correct, making the data trustworthy. This moves their online profile from a statistical estimation by corporate entities to an accurate and verifiable profile under their own control. + +IOTA Identity allows a new internet without usernames, passwords, endlessly repeated forms or data harvesting. Users have ultimate control and can choose to supply service providers with their personal data, who in return provide personalized experiences. Data will still flow, and perhaps even more than before, but it will always be in the individual's interest instead of a corporation's. People will gain additional benefits in sharing their data, either in monetary value or improved customer experience. This system is impossible in non-neutral environments such as permissioned or fee-based ledgers. + +Governmental mechanisms for building _digital identities_ are currently being established throughout Europe and Asia, with demand increasing around the globe. However, they are managed by single entities and restricted to the governments that created them. By decentralizing a framework for these standards to adapt to, we have a system for intergovernmental verification of individuals and devices. A person’s digital identification will be transferable across borders like a passport. However, it will no longer require the trust of the issuing government due to the digital trust established by the open and auditable system. + +### Identity for Organizations + +:::info GDPR + +IOTA Identity allows organizations to comply with GDPR in a cost-efficient and privacy-enabling manner + +::: + +Corporations are associated with greed and abuse of power. This reputation stems from the role some have chosen to take within society. Corporations are trusted with our data, but often do not act responsibly; vulnerability, fix, patch, repeat. In software and systems, we have seen this cycle repeat. Headlines on data leaks are now an ever-present feature in the news. + +IOTA Identity presents an opportunity for companies to embrace a new role in the ecosystem. Traditional approaches do not provide cost-efficient solutions to new legislation like GDPR. IOTA Identity enables organizations to change their processes to comply with the new regulations in a cost-efficient and privacy-enabling manner. Features of “Data Protection and Privacy by Design” shift responsibility over Personal Identifiable Information (PII) from organization to customer, and organizations no longer need to store that data. The relationship between customer and organization is also tightened as communication via a third-party Identity provider like Google or Facebook is no longer needed. + +Due to Know-Your-Customer (KYC) and Anti-Money Laundering (AML) obligations, companies can be certain who their customers are. These services also provide unique insight into their customers’ data. These insights can be combined and translated into verifiable credentials, providing a new “Trust Anchor” service with the potential for new business models. KYC and AML credentials would return the autonomy of personal data to the customer. Once companies accept other companies' KYC and AML credentials, the enrollment time for new customers is significantly reduced, as are the costs. With the personal data secured by the customer, companies can afford to store less data in their databases, reducing risk and responsibility and fulfilling the goals of legislation such as GDPR. + +Organizations that have their own decentralized identities can also combat fraud and increase control over their online brand. Companies can sign invoices and agreements using their decentralized identities. While interacting with the customers, they will also be able to reliably identify themselves. + +### Identity for Things + +:::info TRUST + +IOTA Identity adds the missing key ingredient for the "Economy of Things": Trust. + +::: + +With Identity of Things (IDoT), devices are provided with a unique global identity that are able to prove many attributes, including their capabilities, specifications, and authenticity. People, organizations, and other devices will only pay for devices that can prove their ability to fulfill the required task. This basis of trust prevents fraudulent activity. Additionally, using the IOTA ledger, the task's progress can be immutably logged. Combining the IOTA protocol and the IOTA Identity framework, we can automate the entire interaction between all parties without requiring predefined trust. The [Industry Marketplace](https://industry.iota.org/) provides a perfect example of how this framework and level of autonomy work. + +There is a growth in applications that generate Digital Twins for physical devices or objects, such as the Asset Administration Shell (AAS) developed for our Industry Marketplace. Digital twins are online profiles representing a device or object. They provide a virtual state that mirrors reality by emulating the device or object’s physical state through data input sources like sensors. A digital twin is often used to monitor states and execute actions based on the information. Digital twins are only rarely shared outside the associated application and organization due to the complexities in sharing and matching profiles. However, empowered with a digital identity, digital twin sharing would become possible. Once data is verifiable and trusted, digital twins can form the basis for the digital representation of physical devices and objects. This allows other identities to interact with them automatically and provide services such as predictive maintenance. + +Security is a major barrier to advancing technologies that use IoT. Whether it is the smart devices in our homes or at a larger scale, the critical infrastructure of organizations and cities, security must be at the core. It is central to any globally unifying identity solution. By integrating advanced research in cryptography and digital ledgers and combining it with a scalable access and management system, security will become a core functionality of the systems we build. By using scalable device DIDs, integrating verification and reputation schemes, and allowing for transparent tamper-proof accountability, we begin to understand how we can future-proof the security of our systems, allowing us to start trusting the process and not the patch. + +### One Framework. Any Identity + +The IOTA Identity framework serves as a ubiquitous layer of trust for the internet. Whether it's people, organizations, or things, the framework enables the creation of digital identities, fosters trust-building through verifiable credentials, and ensures seamless interaction among different entities. + +### Why IOTA? + +IOTA stands apart as a scalable, feeless Distributed Ledger Technology (DLT), suitable for a universal identity solution. Some features of IOTA include: + +* **Cost-effectiveness**: Usually, minting decentralized identities costs fees. IOTA Identity has redeemable and predictable deposits but no fees. +* **High availability**: Identities are always available on all network nodes - for holders, issuers, and verifiers. +* **Security**: Write access to identities is secured through multi-level control structures with key rotation capabilities, allowing for backup access and recoverability. +* **Integrity**: Updates go through the same mechanisms that secure the IOTA network, guaranteeing consistent state and history of all identities. diff --git a/docs/content/guides/developer/iota-identity/workflow.mdx b/docs/content/guides/developer/iota-identity/workflow.mdx new file mode 100644 index 00000000000..70449a8673c --- /dev/null +++ b/docs/content/guides/developer/iota-identity/workflow.mdx @@ -0,0 +1,179 @@ +--- +title: Identity.rs workflow +sidebar_label: Workflow +description: Learn about the software development process of the IOTA Identity repository. +image: /img/Identity_icon.png +tags: + - Workflow + - Contribute + - GitHub + - explanation +--- + +# Identity Workflow + +In this article you will learn about the software development process for the IOTA Identity repository as well as key terms, functions, and the overall operability of the workflow components. + +## Issues + +Issues are opened when a certain task or problem is noted but cannot immediately be fixed. Issues may contain bug reports, requests, or larger topics. Please use the correct GitHub issue template for your issue type. Only IOTA Foundation members should use the task templates flagged for maintainers. You should make sure to [label](#issue-labels) the issue correctly. As a contributor, you may also add issues to a certain [project](https://github.com/iotaledger/identity.rs/projects/). + +## Git + +### Pull Requests + +New branches should be pushed to the GitHub repository as soon as possible, making them public to all contributors. In addition, a pull request (PR) should be opened in draft status, describing the goals and any requirements of the changes. To generate good [changelogs](#changelog), a PR title must be written in a way that is suitable as a changelog entry while the PR must be [labeled](#pr-labels) correctly. + +Any code written should frequently be committed and pushed back to the GitHub branch. This acts as both a back-up mechanism and provides transparency towards other contributors and the community. You should also pull from the origin branch of the PR regularly to prevent merge conflicts. + +Other contributors are encouraged to provide feedback on a PR during its development. A PR should be flagged as 'ready for review' once the PR has implemented all changes and no further commits are planned by the main contributors. The repository requires a review to be provided by at least one (other) developer in the team that works in the same language or has knowledge of the work before it can be merged. For larger PRs, the review of two maintainers is recommended. + +Once a PR is approved, the preferred method is "squash-and-merge" for non-epic branches to keep the destination branch clean and allow for many small commits while work is in-progress. Epic branches must instead be merged with the merge commits of included PRs intact, so the [changelog generator](#changelog) can detect included changes. Once merged in, the source branch may be deleted. + +### Branches + +IOTA Identity always has two permanent branches: `main` and `dev`. Both branches are protected and disallow direct commits; the only changes allowed are from pull requests approved and merged by maintainers. + +#### [Main](https://github.com/iotaledger/identity.rs/tree/main) (main) + +The `main` branch contains a stable version of the code that is released towards package managers such as `crates.io` and `npm`. This branch only accepts PRs that merge from `release` or `hotfix` branches. + +#### [Dev](https://github.com/iotaledger/identity.rs) (dev) + +The `dev` branch contains a frequently updated version of the code that is released towards package managers under a development flag. These releases may contain breaking changes without a strong notice towards developers using them. While the `dev` branch may get frequent updates, it may not contain unfinished features. Any large, multi-PR feature should be committed to a long-lived `epic` branch created specifically for that feature. + +### Work Branches + +These are branches that developers work on directly. Their names should be prefixed appropriately with one of the following categories. For example, a PR fixing a null pointer bug in the Wasm bindings might be created from a branch called `fix/client-non-null`. + +#### Feature (feat/, doc/, chore/, fix/) + +Singular PR contributions should create either a `feat`, `doc`, `chore`, or `fix` branch, depending on the type of changes. These may be branched from either the `dev` branch or an `epic` branch. If the number of lines of code are going to be relatively small and the work completed in a single PR, the branch should be created from `dev` and merged back into `dev` once completed. Otherwise, the branches should be created from their associated `epic` branch and be merged back into the same `epic` branch. + +- `feat` branches should contain changes to the code that expand or modify functionality. They should also include updates to the documentation and examples related to the feature, though `doc` branches may be used to catch up on documenting a feature. +- `doc` branches contain changes to code documentation or the wiki. These PRs should be kept relatively small to avoid burdening a reviewer with too many documentation updates at once. For example, during a documentation catch-up, we will have a branch or PR per documentation page. +- `chore` branches are short-lived branches that contain no significant features or functionality changes, but rather smaller fixes such as typos, code fixes, minor refactors, and CI changes. +- `fix` branches correct bugs such as compilation errors or where existing features do not behave as expected, generally without introducing any new functionality or breaking changes. + +We recommend integrating `dev` or `epic` regularly, depending on where the branch started, to reduce the possibility and potential size of merge conflicts. + +#### Epic (epic/) + +Long-lived `epic` branches should be created as soon as a feature is expected to require more than one PR. The `epic` branch should be branched from `dev` and should only accept merges that are related to the feature being developed. A PR should be opened as soon as the branch is created to publicly notify contributors about the development, the goals and requirements of the feature, and the existence of the branch. It is recommended you integrate `dev` often to reduce the possibility and potential size of merge conflicts. Epic branches must not be squash-merged, otherwise the [changelog generator](#changelog) will not detect its constituent PRs. + +### Semantic Versioning + +Semantic Versioning (SemVer) describes a methodology for versioning of software to convey meaning and guarantees through the version string. A typical version string looks like `2.3.1`, where `2` is called the major version, `3` the minor version and `1` the patch or bugfix version. + +The central idea is that every part of the version string conveys meaning. A major change introduces behavior that is incompatible with previous versions of the software, while a minor change adds backwards-compatible functionality and a patch simply fixes a problem. So just by looking at the version string, an implementer will understand the effort needed to integrate a new version. + +For more detailed information and an overview of advanced features, see [Semantic Versioning 2.0.0](https://semver.org/). Though this is not to be confused with [Sentimental Versioning](http://sentimentalversioning.org/). + +### Changelog + +A changelog is a file describing a software project for humans to grasp the type and content of changes from version to version. Changelogs are closely related to the versioning of software, since individual changes are grouped into versions that are, in our case, referenced by a [SemVer string](#semantic-versioning). We generally follow the recommendations from [keepachangelog](https://keepachangelog.com/en/1.0.0/). The changelog in this project is generated from the titles and [labels](#pr-labels) of [pull requests](#pull-requests). + +#### PR labels + +Labels are used to categorize changes in [pull requests](#pull-requests). Adding a label will include the labeled [PR](#pull-requests) title in the related section of the generated [changelog](#changelog). + +Changelogs are generated for the core Rust library and each binding separately. To attach a PR to a specific changelog, use the following labels: + +##### `Rust` + +This includes the PR in the core Rust library changelog. + +##### `Wasm` + +This includes the PR in the WASM bindings changelog. + +It is also necessary to add an appropriate label for the type of change in the PR. The following labels determine in which section a PR title will appear: + +##### Changed + +Maps to the major version of [Semantic Versioning](#semantic-versioning). +labels: `Breaking change` + +##### Added + +Maps to the minor version of [Semantic Versioning](#semantic-versioning). +labels: `Added` + +##### Patch + +Maps to the patch version of [Semantic Versioning](#semantic-versioning). +labels: `Patch` + +##### Deprecated + +Marks features that will be removed in the feature. No special version consideration should apply here, since the feature did not change yet. +labels: `Deprecated` + +##### Removed + +Marks features as being removed. Typically the features should have been deprecated in the previous version. This maps to the major version of [Semantic Versioning](#semantic-versioning). +labels: `Removed` + +##### Excluded tags + +Marks changes that should not be part of the changelog. This should only be used for documentation and rare exceptions. +labels: `Documentation`, `No changelog` + +Please note that a PR can only be listed in one section of a changelog. So attaching the labels `Rust` `Added` `Patch` to a PR, for example, is invalid because `Added` and `Patch` conflict. + +##### Release summary + +To attach a release summary to a version in the changelog, an issue with the label `release-summary` must be created. Create a GitHub milestone matching the version you want to describe and attach it to the issue. The issue can be closed immediately. The text of the issue will be included in the changelog as the release summary. + +### Issue Labels + +The following labels are used to categorize issues but do not have any effect on changelogs: `Request`, `Enhancement`, `Bug`, `Chore`, `Dependencies`, `Help wanted`, `Duplicate`, `Wontfix`. + +## Release + +With the release process, we can deliver versions of our software to the community. We use sensible automation where it helps to remove tedium. However, some steps that require active decision-making remain manual. + +The final list of changes from the [changelog](#changelog) informs the version of the release. If at least one change mapping to a major version is included, the major version needs to be incremented. In that case, the minor and patch versions are set to `0`. If there are no changes related to a major version, but changes related to a minor version are present, the minor version needs to be incremented while the patch version is set to `0`. Otherwise, only the patch version is incremented. Determining the version of the release is the responsibility of the person performing the release. + +The determined version of the release is used to create the [hotfix](#hotfix) or [release](#release) branch. For example, a major release from the previous version `v2.3.1` will create the `release/v3.0.0` branch. + +Notice the `v` in front of the version. We [tag](https://git-scm.com/book/en/v2/Git-Basics-Tagging) all release in git in the form of `vMAJOR.MINOR.PATCH`. For bindings, we prefix the tag with the binding name, so a tag for Wasm would look like `wasm-v1.2.3`. Bindings and the core Rust library are versioned and released independently. + +Additionally, we may release `dev` versions separately for both bindings and the core Rust library. These releases are meant as a preview of upcoming versions. For example, if the current version is `1.2.3` with the tag `v1.2.3`, we may release `v1.3.0-dev.1` which is then superseded by the actual `1.3.0` release. + +You should follow these steps to create a release: + +1. Ensure all the changes you want to release are on the `dev` branch. +2. Select the appropriate GitHub Actions workflow, e.g. `Rust Create Release PR`. + 2.1. Decide if you want to create a `dev` or `main` release. + 2.2. Determine the next version string. + 2.3. Run the workflow. The workflow will create a PR from `dev` targeting `dev` with release related changes. +3. Review the PR. + 3.1. The PR will update the changelog, check that it has all expected entries in the appropriate sections and the determined version matches the changelog according to [SemVer](#semantic-versioning). + 3.2. The PR will update project version strings, ensure these are correct and match the expected version. + 3.3. Refer to [Troubleshooting](#troubleshooting) if anything is incorrect. +4. Merge the PR. + 4.1. On merging to `dev`, an automatic workflow is triggered that builds and publishes artifacts to the appropriate package manager (`crates.io` for Rust, `npm` for the WASM bindings), and creates a GitHub Release (only for `main` version releases of the core Rust library). +5. For `main` version releases, merge the `dev` branch into the `main` branch. + +### Troubleshooting + +#### The changelog entries have the wrong description in the release PR + +Update the titles of the relevant PRs, then re-run the workflow with the same parameters. The release PR will be updated with the new changelog. + +#### The changelog in the release PR is missing entries, has unrelated entries, or entries in the wrong section + +Fix the [labels](#pr-labels) on the relevant PRs, then re-run the workflow with the same parameters. The release PR will be updated with the new changelog. + +#### The release description in the release PR is missing or wrong + +Fix the issue description, milestone, and label according to the [release summaries guide](#release-summary) and re-run the workflow with the same parameters. The release PR will be updated with the new changelog. + +#### Features or code are missing from the release + +Merge the code into the `dev` branch, then re-run the workflow with the same parameters. The release PR will be updated with the changes. + +#### I want to abort the release for any reason + +Close the PR. You can reopen it later. // TODO: can I just re-run the workflow? Maybe that needs an "I want to resume an aborted release" section? diff --git a/docs/content/references/iota-identity/wasm.md b/docs/content/references/iota-identity/wasm.md new file mode 100644 index 00000000000..48885d9e986 --- /dev/null +++ b/docs/content/references/iota-identity/wasm.md @@ -0,0 +1,7684 @@ +--- +title: WASM API Reference +description: WASM API reference. +image: /img/Identity_icon.png +tags: + - WASM + - API Reference +--- +# Wasm Api Reference + +## Classes + +
+ +## Members + +
+
StatusCheck
+

Controls validation behaviour when checking whether or not a credential has been revoked by its +credentialStatus.

+
+
Strict
+

Validate the status if supported, reject any unsupported +credentialStatus types.

+

Only RevocationBitmap2022 is currently supported.

+

This is the default.

+
+
SkipUnsupported
+

Validate the status if supported, skip any unsupported +credentialStatus types.

+
+
SkipAll
+

Skip all status checks.

+
+
CredentialStatus
+
+
PayloadType
+
+
ProofAlgorithm
+
+
StatusPurpose
+

Purpose of a StatusList2021.

+
+
FailFast
+

Declares when validation should return if an error occurs.

+
+
AllErrors
+

Return all errors that occur during validation.

+
+
FirstError
+

Return after the first error occurs.

+
+
StateMetadataEncoding
+
+
SerializationType
+
+
MethodRelationship
+
+
PresentationProofAlgorithm
+
+
SubjectHolderRelationship
+

Declares how credential subjects must relate to the presentation holder.

+

See also the Subject-Holder Relationship section of the specification.

+
+
AlwaysSubject
+

The holder must always match the subject on all credentials, regardless of their nonTransferable property. +This variant is the default.

+
+
SubjectOnNonTransferable
+

The holder must match the subject only for credentials where the nonTransferable property is true.

+
+
Any
+

The holder is not required to have any kind of relationship to any credential subject.

+
+
+ +## Functions + +
+
encodeB64(data)string
+

Encode the given bytes in url-safe base64.

+
+
decodeB64(data)Uint8Array
+

Decode the given url-safe base64-encoded slice into its raw bytes.

+
+
start()
+

Initializes the console error panic hook for better error messages

+
+
verifyEd25519(alg, signingInput, decodedSignature, publicKey)
+

Verify a JWS signature secured with the EdDSA algorithm and curve Ed25519.

+

This function is useful when one is composing a IJwsVerifier that delegates +EdDSA verification with curve Ed25519 to this function.

+

Warning

+

This function does not check whether alg = EdDSA in the protected header. Callers are expected to assert this +prior to calling the function.

+
+
+ + + +## CoreDID +A method-agnostic Decentralized Identifier (DID). + +**Kind**: global class + +* [CoreDID](#CoreDID) + * _instance_ + * [.setMethodName(value)](#CoreDID+setMethodName) + * [.setMethodId(value)](#CoreDID+setMethodId) + * [.scheme()](#CoreDID+scheme) ⇒ string + * [.authority()](#CoreDID+authority) ⇒ string + * [.method()](#CoreDID+method) ⇒ string + * [.methodId()](#CoreDID+methodId) ⇒ string + * [.join(segment)](#CoreDID+join) ⇒ [DIDUrl](#DIDUrl) + * [.toUrl()](#CoreDID+toUrl) ⇒ [DIDUrl](#DIDUrl) + * [.intoUrl()](#CoreDID+intoUrl) ⇒ [DIDUrl](#DIDUrl) + * [.toString()](#CoreDID+toString) ⇒ string + * [.toCoreDid()](#CoreDID+toCoreDid) ⇒ [CoreDID](#CoreDID) + * [.toJSON()](#CoreDID+toJSON) ⇒ any + * [.clone()](#CoreDID+clone) ⇒ [CoreDID](#CoreDID) + * _static_ + * [.parse(input)](#CoreDID.parse) ⇒ [CoreDID](#CoreDID) + * [.validMethodName(value)](#CoreDID.validMethodName) ⇒ boolean + * [.validMethodId(value)](#CoreDID.validMethodId) ⇒ boolean + * [.fromJSON(json)](#CoreDID.fromJSON) ⇒ [CoreDID](#CoreDID) + + + +### coreDID.setMethodName(value) +Set the method name of the [CoreDID](#CoreDID). + +**Kind**: instance method of [CoreDID](#CoreDID) + +| Param | Type | +| --- | --- | +| value | string | + + + +### coreDID.setMethodId(value) +Set the method-specific-id of the `DID`. + +**Kind**: instance method of [CoreDID](#CoreDID) + +| Param | Type | +| --- | --- | +| value | string | + + + +### coreDID.scheme() ⇒ string +Returns the [CoreDID](#CoreDID) scheme. + +E.g. +- `"did:example:12345678" -> "did"` +- `"did:iota:smr:12345678" -> "did"` + +**Kind**: instance method of [CoreDID](#CoreDID) + + +### coreDID.authority() ⇒ string +Returns the [CoreDID](#CoreDID) authority: the method name and method-id. + +E.g. +- `"did:example:12345678" -> "example:12345678"` +- `"did:iota:smr:12345678" -> "iota:smr:12345678"` + +**Kind**: instance method of [CoreDID](#CoreDID) + + +### coreDID.method() ⇒ string +Returns the [CoreDID](#CoreDID) method name. + +E.g. +- `"did:example:12345678" -> "example"` +- `"did:iota:smr:12345678" -> "iota"` + +**Kind**: instance method of [CoreDID](#CoreDID) + + +### coreDID.methodId() ⇒ string +Returns the [CoreDID](#CoreDID) method-specific ID. + +E.g. +- `"did:example:12345678" -> "12345678"` +- `"did:iota:smr:12345678" -> "smr:12345678"` + +**Kind**: instance method of [CoreDID](#CoreDID) + + +### coreDID.join(segment) ⇒ [DIDUrl](#DIDUrl) +Construct a new [DIDUrl](#DIDUrl) by joining with a relative DID Url string. + +**Kind**: instance method of [CoreDID](#CoreDID) + +| Param | Type | +| --- | --- | +| segment | string | + + + +### coreDID.toUrl() ⇒ [DIDUrl](#DIDUrl) +Clones the [CoreDID](#CoreDID) into a [DIDUrl](#DIDUrl). + +**Kind**: instance method of [CoreDID](#CoreDID) + + +### coreDID.intoUrl() ⇒ [DIDUrl](#DIDUrl) +Converts the [CoreDID](#CoreDID) into a [DIDUrl](#DIDUrl), consuming it. + +**Kind**: instance method of [CoreDID](#CoreDID) + + +### coreDID.toString() ⇒ string +Returns the [CoreDID](#CoreDID) as a string. + +**Kind**: instance method of [CoreDID](#CoreDID) + + +### coreDID.toCoreDid() ⇒ [CoreDID](#CoreDID) +**Kind**: instance method of [CoreDID](#CoreDID) + + +### coreDID.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [CoreDID](#CoreDID) + + +### coreDID.clone() ⇒ [CoreDID](#CoreDID) +Deep clones the object. + +**Kind**: instance method of [CoreDID](#CoreDID) + + +### CoreDID.parse(input) ⇒ [CoreDID](#CoreDID) +Parses a [CoreDID](#CoreDID) from the given `input`. + +### Errors + +Throws an error if the input is not a valid [CoreDID](#CoreDID). + +**Kind**: static method of [CoreDID](#CoreDID) + +| Param | Type | +| --- | --- | +| input | string | + + + +### CoreDID.validMethodName(value) ⇒ boolean +Validates whether a string is a valid DID method name. + +**Kind**: static method of [CoreDID](#CoreDID) + +| Param | Type | +| --- | --- | +| value | string | + + + +### CoreDID.validMethodId(value) ⇒ boolean +Validates whether a string is a valid `DID` method-id. + +**Kind**: static method of [CoreDID](#CoreDID) + +| Param | Type | +| --- | --- | +| value | string | + + + +### CoreDID.fromJSON(json) ⇒ [CoreDID](#CoreDID) +Deserializes an instance from a JSON object. + +**Kind**: static method of [CoreDID](#CoreDID) + +| Param | Type | +| --- | --- | +| json | any | + + + +## CoreDocument +A method-agnostic DID Document. + +Note: All methods that involve reading from this class may potentially raise an error +if the object is being concurrently modified. + +**Kind**: global class + +* [CoreDocument](#CoreDocument) + * [new CoreDocument(values)](#new_CoreDocument_new) + * _instance_ + * [.id()](#CoreDocument+id) ⇒ [CoreDID](#CoreDID) + * [.setId(id)](#CoreDocument+setId) + * [.controller()](#CoreDocument+controller) ⇒ [Array.<CoreDID>](#CoreDID) + * [.setController(controllers)](#CoreDocument+setController) + * [.alsoKnownAs()](#CoreDocument+alsoKnownAs) ⇒ Array.<string> + * [.setAlsoKnownAs(urls)](#CoreDocument+setAlsoKnownAs) + * [.verificationMethod()](#CoreDocument+verificationMethod) ⇒ [Array.<VerificationMethod>](#VerificationMethod) + * [.authentication()](#CoreDocument+authentication) ⇒ Array.<(DIDUrl\|VerificationMethod)> + * [.assertionMethod()](#CoreDocument+assertionMethod) ⇒ Array.<(DIDUrl\|VerificationMethod)> + * [.keyAgreement()](#CoreDocument+keyAgreement) ⇒ Array.<(DIDUrl\|VerificationMethod)> + * [.capabilityDelegation()](#CoreDocument+capabilityDelegation) ⇒ Array.<(DIDUrl\|VerificationMethod)> + * [.capabilityInvocation()](#CoreDocument+capabilityInvocation) ⇒ Array.<(DIDUrl\|VerificationMethod)> + * [.properties()](#CoreDocument+properties) ⇒ Map.<string, any> + * [.setPropertyUnchecked(key, value)](#CoreDocument+setPropertyUnchecked) + * [.service()](#CoreDocument+service) ⇒ [Array.<Service>](#Service) + * [.insertService(service)](#CoreDocument+insertService) + * [.removeService(didUrl)](#CoreDocument+removeService) ⇒ [Service](#Service) \| undefined + * [.resolveService(query)](#CoreDocument+resolveService) ⇒ [Service](#Service) \| undefined + * [.methods([scope])](#CoreDocument+methods) ⇒ [Array.<VerificationMethod>](#VerificationMethod) + * [.verificationRelationships()](#CoreDocument+verificationRelationships) ⇒ Array.<(DIDUrl\|VerificationMethod)> + * [.insertMethod(method, scope)](#CoreDocument+insertMethod) + * [.removeMethod(did)](#CoreDocument+removeMethod) ⇒ [VerificationMethod](#VerificationMethod) \| undefined + * [.resolveMethod(query, [scope])](#CoreDocument+resolveMethod) ⇒ [VerificationMethod](#VerificationMethod) \| undefined + * [.attachMethodRelationship(didUrl, relationship)](#CoreDocument+attachMethodRelationship) ⇒ boolean + * [.detachMethodRelationship(didUrl, relationship)](#CoreDocument+detachMethodRelationship) ⇒ boolean + * [.verifyJws(jws, options, signatureVerifier, [detachedPayload])](#CoreDocument+verifyJws) ⇒ [DecodedJws](#DecodedJws) + * [.revokeCredentials(serviceQuery, indices)](#CoreDocument+revokeCredentials) + * [.unrevokeCredentials(serviceQuery, indices)](#CoreDocument+unrevokeCredentials) + * [.clone()](#CoreDocument+clone) ⇒ [CoreDocument](#CoreDocument) + * [._shallowCloneInternal()](#CoreDocument+_shallowCloneInternal) ⇒ [CoreDocument](#CoreDocument) + * [._strongCountInternal()](#CoreDocument+_strongCountInternal) ⇒ number + * [.toJSON()](#CoreDocument+toJSON) ⇒ any + * [.generateMethod(storage, keyType, alg, fragment, scope)](#CoreDocument+generateMethod) ⇒ Promise.<string> + * [.purgeMethod(storage, id)](#CoreDocument+purgeMethod) ⇒ Promise.<void> + * [.createJws(storage, fragment, payload, options)](#CoreDocument+createJws) ⇒ [Promise.<Jws>](#Jws) + * [.createCredentialJwt(storage, fragment, credential, options, [custom_claims])](#CoreDocument+createCredentialJwt) ⇒ [Promise.<Jwt>](#Jwt) + * [.createPresentationJwt(storage, fragment, presentation, signature_options, presentation_options)](#CoreDocument+createPresentationJwt) ⇒ [Promise.<Jwt>](#Jwt) + * _static_ + * [.fromJSON(json)](#CoreDocument.fromJSON) ⇒ [CoreDocument](#CoreDocument) + + + +### new CoreDocument(values) +Creates a new [CoreDocument](#CoreDocument) with the given properties. + + +| Param | Type | +| --- | --- | +| values | ICoreDocument | + + + +### coreDocument.id() ⇒ [CoreDID](#CoreDID) +Returns a copy of the DID Document `id`. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + + +### coreDocument.setId(id) +Sets the DID of the document. + +### Warning + +Changing the identifier can drastically alter the results of +`resolve_method`, `resolve_service` and the related +[DID URL dereferencing](https://w3c-ccg.github.io/did-resolution/#dereferencing) algorithm. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| id | [CoreDID](#CoreDID) | + + + +### coreDocument.controller() ⇒ [Array.<CoreDID>](#CoreDID) +Returns a copy of the document controllers. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + + +### coreDocument.setController(controllers) +Sets the controllers of the DID Document. + +Note: Duplicates will be ignored. +Use `null` to remove all controllers. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| controllers | [CoreDID](#CoreDID) \| [Array.<CoreDID>](#CoreDID) \| null | + + + +### coreDocument.alsoKnownAs() ⇒ Array.<string> +Returns a copy of the document's `alsoKnownAs` set. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + + +### coreDocument.setAlsoKnownAs(urls) +Sets the `alsoKnownAs` property in the DID document. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| urls | string \| Array.<string> \| null | + + + +### coreDocument.verificationMethod() ⇒ [Array.<VerificationMethod>](#VerificationMethod) +Returns a copy of the document's `verificationMethod` set. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + + +### coreDocument.authentication() ⇒ Array.<(DIDUrl\|VerificationMethod)> +Returns a copy of the document's `authentication` set. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + + +### coreDocument.assertionMethod() ⇒ Array.<(DIDUrl\|VerificationMethod)> +Returns a copy of the document's `assertionMethod` set. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + + +### coreDocument.keyAgreement() ⇒ Array.<(DIDUrl\|VerificationMethod)> +Returns a copy of the document's `keyAgreement` set. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + + +### coreDocument.capabilityDelegation() ⇒ Array.<(DIDUrl\|VerificationMethod)> +Returns a copy of the document's `capabilityDelegation` set. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + + +### coreDocument.capabilityInvocation() ⇒ Array.<(DIDUrl\|VerificationMethod)> +Returns a copy of the document's `capabilityInvocation` set. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + + +### coreDocument.properties() ⇒ Map.<string, any> +Returns a copy of the custom DID Document properties. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + + +### coreDocument.setPropertyUnchecked(key, value) +Sets a custom property in the DID Document. +If the value is set to `null`, the custom property will be removed. + +### WARNING + +This method can overwrite existing properties like `id` and result in an invalid document. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| key | string | +| value | any | + + + +### coreDocument.service() ⇒ [Array.<Service>](#Service) +Returns a set of all [Service](#Service) in the document. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + + +### coreDocument.insertService(service) +Add a new [Service](#Service) to the document. + +Errors if there already exists a service or verification method with the same id. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| service | [Service](#Service) | + + + +### coreDocument.removeService(didUrl) ⇒ [Service](#Service) \| undefined +Remove a [Service](#Service) identified by the given [DIDUrl](#DIDUrl) from the document. + +Returns `true` if the service was removed. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| didUrl | [DIDUrl](#DIDUrl) | + + + +### coreDocument.resolveService(query) ⇒ [Service](#Service) \| undefined +Returns the first [Service](#Service) with an `id` property matching the provided `query`, +if present. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| query | [DIDUrl](#DIDUrl) \| string | + + + +### coreDocument.methods([scope]) ⇒ [Array.<VerificationMethod>](#VerificationMethod) +Returns a list of all [VerificationMethod](#VerificationMethod) in the DID Document, +whose verification relationship matches `scope`. + +If `scope` is not set, a list over the **embedded** methods is returned. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| [scope] | [MethodScope](#MethodScope) \| undefined | + + + +### coreDocument.verificationRelationships() ⇒ Array.<(DIDUrl\|VerificationMethod)> +Returns an array of all verification relationships. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + + +### coreDocument.insertMethod(method, scope) +Adds a new `method` to the document in the given `scope`. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| method | [VerificationMethod](#VerificationMethod) | +| scope | [MethodScope](#MethodScope) | + + + +### coreDocument.removeMethod(did) ⇒ [VerificationMethod](#VerificationMethod) \| undefined +Removes all references to the specified Verification Method. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| did | [DIDUrl](#DIDUrl) | + + + +### coreDocument.resolveMethod(query, [scope]) ⇒ [VerificationMethod](#VerificationMethod) \| undefined +Returns a copy of the first verification method with an `id` property +matching the provided `query` and the verification relationship +specified by `scope`, if present. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| query | [DIDUrl](#DIDUrl) \| string | +| [scope] | [MethodScope](#MethodScope) \| undefined | + + + +### coreDocument.attachMethodRelationship(didUrl, relationship) ⇒ boolean +Attaches the relationship to the given method, if the method exists. + +Note: The method needs to be in the set of verification methods, +so it cannot be an embedded one. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| didUrl | [DIDUrl](#DIDUrl) | +| relationship | [MethodRelationship](#MethodRelationship) | + + + +### coreDocument.detachMethodRelationship(didUrl, relationship) ⇒ boolean +Detaches the given relationship from the given method, if the method exists. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| didUrl | [DIDUrl](#DIDUrl) | +| relationship | [MethodRelationship](#MethodRelationship) | + + + +### coreDocument.verifyJws(jws, options, signatureVerifier, [detachedPayload]) ⇒ [DecodedJws](#DecodedJws) +Decodes and verifies the provided JWS according to the passed `options` and `signatureVerifier`. + If no `signatureVerifier` argument is provided a default verifier will be used that is (only) capable of +verifying EdDSA signatures. + +Regardless of which options are passed the following conditions must be met in order for a verification attempt to +take place. +- The JWS must be encoded according to the JWS compact serialization. +- The `kid` value in the protected header must be an identifier of a verification method in this DID document, +or set explicitly in the `options`. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| jws | [Jws](#Jws) | +| options | [JwsVerificationOptions](#JwsVerificationOptions) | +| signatureVerifier | IJwsVerifier | +| [detachedPayload] | string \| undefined | + + + +### coreDocument.revokeCredentials(serviceQuery, indices) +If the document has a [RevocationBitmap](#RevocationBitmap) service identified by `serviceQuery`, +revoke all specified `indices`. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| serviceQuery | [DIDUrl](#DIDUrl) \| string | +| indices | number \| Array.<number> | + + + +### coreDocument.unrevokeCredentials(serviceQuery, indices) +If the document has a [RevocationBitmap](#RevocationBitmap) service identified by `serviceQuery`, +unrevoke all specified `indices`. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| serviceQuery | [DIDUrl](#DIDUrl) \| string | +| indices | number \| Array.<number> | + + + +### coreDocument.clone() ⇒ [CoreDocument](#CoreDocument) +Deep clones the [CoreDocument](#CoreDocument). + +**Kind**: instance method of [CoreDocument](#CoreDocument) + + +### coreDocument.\_shallowCloneInternal() ⇒ [CoreDocument](#CoreDocument) +### Warning +This is for internal use only. Do not rely on or call this method. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + + +### coreDocument.\_strongCountInternal() ⇒ number +### Warning +This is for internal use only. Do not rely on or call this method. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + + +### coreDocument.toJSON() ⇒ any +Serializes to a plain JS representation. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + + +### coreDocument.generateMethod(storage, keyType, alg, fragment, scope) ⇒ Promise.<string> +Generate new key material in the given `storage` and insert a new verification method with the corresponding +public key material into the DID document. + +- If no fragment is given the `kid` of the generated JWK is used, if it is set, otherwise an error is returned. +- The `keyType` must be compatible with the given `storage`. `Storage`s are expected to export key type constants +for that use case. + +The fragment of the generated method is returned. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| storage | [Storage](#Storage) | +| keyType | string | +| alg | JwsAlgorithm | +| fragment | string \| undefined | +| scope | [MethodScope](#MethodScope) | + + + +### coreDocument.purgeMethod(storage, id) ⇒ Promise.<void> +Remove the method identified by the `fragment` from the document and delete the corresponding key material in +the `storage`. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| storage | [Storage](#Storage) | +| id | [DIDUrl](#DIDUrl) | + + + +### coreDocument.createJws(storage, fragment, payload, options) ⇒ [Promise.<Jws>](#Jws) +Sign the `payload` according to `options` with the storage backed private key corresponding to the public key +material in the verification method identified by the given `fragment. + +Upon success a string representing a JWS encoded according to the Compact JWS Serialization format is returned. +See [RFC7515 section 3.1](https://www.rfc-editor.org/rfc/rfc7515#section-3.1). + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| storage | [Storage](#Storage) | +| fragment | string | +| payload | string | +| options | [JwsSignatureOptions](#JwsSignatureOptions) | + + + +### coreDocument.createCredentialJwt(storage, fragment, credential, options, [custom_claims]) ⇒ [Promise.<Jwt>](#Jwt) +Produces a JWT where the payload is produced from the given `credential` +in accordance with [VC Data Model v1.1](https://www.w3.org/TR/vc-data-model/#json-web-token). + +Unless the `kid` is explicitly set in the options, the `kid` in the protected header is the `id` +of the method identified by `fragment` and the JWS signature will be produced by the corresponding +private key backed by the `storage` in accordance with the passed `options`. + +The `custom_claims` can be used to set additional claims on the resulting JWT. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| storage | [Storage](#Storage) | +| fragment | string | +| credential | [Credential](#Credential) | +| options | [JwsSignatureOptions](#JwsSignatureOptions) | +| [custom_claims] | Record.<string, any> \| undefined | + + + +### coreDocument.createPresentationJwt(storage, fragment, presentation, signature_options, presentation_options) ⇒ [Promise.<Jwt>](#Jwt) +Produces a JWT where the payload is produced from the given presentation. +in accordance with [VC Data Model v1.1](https://www.w3.org/TR/vc-data-model/#json-web-token). + +Unless the `kid` is explicitly set in the options, the `kid` in the protected header is the `id` +of the method identified by `fragment` and the JWS signature will be produced by the corresponding +private key backed by the `storage` in accordance with the passed `options`. + +**Kind**: instance method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| storage | [Storage](#Storage) | +| fragment | string | +| presentation | [Presentation](#Presentation) | +| signature_options | [JwsSignatureOptions](#JwsSignatureOptions) | +| presentation_options | [JwtPresentationOptions](#JwtPresentationOptions) | + + + +### CoreDocument.fromJSON(json) ⇒ [CoreDocument](#CoreDocument) +Deserializes an instance from a plain JS representation. + +**Kind**: static method of [CoreDocument](#CoreDocument) + +| Param | Type | +| --- | --- | +| json | any | + + + +## Credential +**Kind**: global class + +* [Credential](#Credential) + * [new Credential(values)](#new_Credential_new) + * _instance_ + * [.context()](#Credential+context) ⇒ Array.<(string\|Record.<string, any>)> + * [.id()](#Credential+id) ⇒ string \| undefined + * [.type()](#Credential+type) ⇒ Array.<string> + * [.credentialSubject()](#Credential+credentialSubject) ⇒ Array.<Subject> + * [.issuer()](#Credential+issuer) ⇒ string \| Issuer + * [.issuanceDate()](#Credential+issuanceDate) ⇒ [Timestamp](#Timestamp) + * [.expirationDate()](#Credential+expirationDate) ⇒ [Timestamp](#Timestamp) \| undefined + * [.credentialStatus()](#Credential+credentialStatus) ⇒ Array.<Status> + * [.credentialSchema()](#Credential+credentialSchema) ⇒ Array.<Schema> + * [.refreshService()](#Credential+refreshService) ⇒ Array.<RefreshService> + * [.termsOfUse()](#Credential+termsOfUse) ⇒ Array.<Policy> + * [.evidence()](#Credential+evidence) ⇒ Array.<Evidence> + * [.nonTransferable()](#Credential+nonTransferable) ⇒ boolean \| undefined + * [.proof()](#Credential+proof) ⇒ [Proof](#Proof) \| undefined + * [.properties()](#Credential+properties) ⇒ Map.<string, any> + * [.setProof([proof])](#Credential+setProof) + * [.toJwtClaims([custom_claims])](#Credential+toJwtClaims) ⇒ Record.<string, any> + * [.toJSON()](#Credential+toJSON) ⇒ any + * [.clone()](#Credential+clone) ⇒ [Credential](#Credential) + * _static_ + * [.BaseContext()](#Credential.BaseContext) ⇒ string + * [.BaseType()](#Credential.BaseType) ⇒ string + * [.createDomainLinkageCredential(values)](#Credential.createDomainLinkageCredential) ⇒ [Credential](#Credential) + * [.fromJSON(json)](#Credential.fromJSON) ⇒ [Credential](#Credential) + + + +### new Credential(values) +Constructs a new [Credential](#Credential). + + +| Param | Type | +| --- | --- | +| values | ICredential | + + + +### credential.context() ⇒ Array.<(string\|Record.<string, any>)> +Returns a copy of the JSON-LD context(s) applicable to the [Credential](#Credential). + +**Kind**: instance method of [Credential](#Credential) + + +### credential.id() ⇒ string \| undefined +Returns a copy of the unique `URI` identifying the [Credential](#Credential) . + +**Kind**: instance method of [Credential](#Credential) + + +### credential.type() ⇒ Array.<string> +Returns a copy of the URIs defining the type of the [Credential](#Credential). + +**Kind**: instance method of [Credential](#Credential) + + +### credential.credentialSubject() ⇒ Array.<Subject> +Returns a copy of the [Credential](#Credential) subject(s). + +**Kind**: instance method of [Credential](#Credential) + + +### credential.issuer() ⇒ string \| Issuer +Returns a copy of the issuer of the [Credential](#Credential). + +**Kind**: instance method of [Credential](#Credential) + + +### credential.issuanceDate() ⇒ [Timestamp](#Timestamp) +Returns a copy of the timestamp of when the [Credential](#Credential) becomes valid. + +**Kind**: instance method of [Credential](#Credential) + + +### credential.expirationDate() ⇒ [Timestamp](#Timestamp) \| undefined +Returns a copy of the timestamp of when the [Credential](#Credential) should no longer be considered valid. + +**Kind**: instance method of [Credential](#Credential) + + +### credential.credentialStatus() ⇒ Array.<Status> +Returns a copy of the information used to determine the current status of the [Credential](#Credential). + +**Kind**: instance method of [Credential](#Credential) + + +### credential.credentialSchema() ⇒ Array.<Schema> +Returns a copy of the information used to assist in the enforcement of a specific [Credential](#Credential) structure. + +**Kind**: instance method of [Credential](#Credential) + + +### credential.refreshService() ⇒ Array.<RefreshService> +Returns a copy of the service(s) used to refresh an expired [Credential](#Credential). + +**Kind**: instance method of [Credential](#Credential) + + +### credential.termsOfUse() ⇒ Array.<Policy> +Returns a copy of the terms-of-use specified by the [Credential](#Credential) issuer. + +**Kind**: instance method of [Credential](#Credential) + + +### credential.evidence() ⇒ Array.<Evidence> +Returns a copy of the human-readable evidence used to support the claims within the [Credential](#Credential). + +**Kind**: instance method of [Credential](#Credential) + + +### credential.nonTransferable() ⇒ boolean \| undefined +Returns whether or not the [Credential](#Credential) must only be contained within a [Presentation](#Presentation) +with a proof issued from the [Credential](#Credential) subject. + +**Kind**: instance method of [Credential](#Credential) + + +### credential.proof() ⇒ [Proof](#Proof) \| undefined +Optional cryptographic proof, unrelated to JWT. + +**Kind**: instance method of [Credential](#Credential) + + +### credential.properties() ⇒ Map.<string, any> +Returns a copy of the miscellaneous properties on the [Credential](#Credential). + +**Kind**: instance method of [Credential](#Credential) + + +### credential.setProof([proof]) +Sets the `proof` property of the [Credential](#Credential). + +Note that this proof is not related to JWT. + +**Kind**: instance method of [Credential](#Credential) + +| Param | Type | +| --- | --- | +| [proof] | [Proof](#Proof) \| undefined | + + + +### credential.toJwtClaims([custom_claims]) ⇒ Record.<string, any> +Serializes the `Credential` as a JWT claims set +in accordance with [VC Data Model v1.1](https://www.w3.org/TR/vc-data-model/#json-web-token). + +The resulting object can be used as the payload of a JWS when issuing the credential. + +**Kind**: instance method of [Credential](#Credential) + +| Param | Type | +| --- | --- | +| [custom_claims] | Record.<string, any> \| undefined | + + + +### credential.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [Credential](#Credential) + + +### credential.clone() ⇒ [Credential](#Credential) +Deep clones the object. + +**Kind**: instance method of [Credential](#Credential) + + +### Credential.BaseContext() ⇒ string +Returns the base JSON-LD context. + +**Kind**: static method of [Credential](#Credential) + + +### Credential.BaseType() ⇒ string +Returns the base type. + +**Kind**: static method of [Credential](#Credential) + + +### Credential.createDomainLinkageCredential(values) ⇒ [Credential](#Credential) +**Kind**: static method of [Credential](#Credential) + +| Param | Type | +| --- | --- | +| values | IDomainLinkageCredential | + + + +### Credential.fromJSON(json) ⇒ [Credential](#Credential) +Deserializes an instance from a JSON object. + +**Kind**: static method of [Credential](#Credential) + +| Param | Type | +| --- | --- | +| json | any | + + + +## CustomMethodData +A custom verification method data format. + +**Kind**: global class + +* [CustomMethodData](#CustomMethodData) + * [new CustomMethodData(name, data)](#new_CustomMethodData_new) + * _instance_ + * [.clone()](#CustomMethodData+clone) ⇒ [CustomMethodData](#CustomMethodData) + * [.toJSON()](#CustomMethodData+toJSON) ⇒ any + * _static_ + * [.fromJSON(json)](#CustomMethodData.fromJSON) ⇒ [CustomMethodData](#CustomMethodData) + + + +### new CustomMethodData(name, data) + +| Param | Type | +| --- | --- | +| name | string | +| data | any | + + + +### customMethodData.clone() ⇒ [CustomMethodData](#CustomMethodData) +Deep clones the object. + +**Kind**: instance method of [CustomMethodData](#CustomMethodData) + + +### customMethodData.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [CustomMethodData](#CustomMethodData) + + +### CustomMethodData.fromJSON(json) ⇒ [CustomMethodData](#CustomMethodData) +Deserializes an instance from a JSON object. + +**Kind**: static method of [CustomMethodData](#CustomMethodData) + +| Param | Type | +| --- | --- | +| json | any | + + + +## DIDUrl +A method agnostic DID Url. + +**Kind**: global class + +* [DIDUrl](#DIDUrl) + * _instance_ + * [.did()](#DIDUrl+did) ⇒ [CoreDID](#CoreDID) + * [.urlStr()](#DIDUrl+urlStr) ⇒ string + * [.fragment()](#DIDUrl+fragment) ⇒ string \| undefined + * [.setFragment([value])](#DIDUrl+setFragment) + * [.path()](#DIDUrl+path) ⇒ string \| undefined + * [.setPath([value])](#DIDUrl+setPath) + * [.query()](#DIDUrl+query) ⇒ string \| undefined + * [.setQuery([value])](#DIDUrl+setQuery) + * [.join(segment)](#DIDUrl+join) ⇒ [DIDUrl](#DIDUrl) + * [.toString()](#DIDUrl+toString) ⇒ string + * [.toJSON()](#DIDUrl+toJSON) ⇒ any + * [.clone()](#DIDUrl+clone) ⇒ [DIDUrl](#DIDUrl) + * _static_ + * [.parse(input)](#DIDUrl.parse) ⇒ [DIDUrl](#DIDUrl) + * [.fromJSON(json)](#DIDUrl.fromJSON) ⇒ [DIDUrl](#DIDUrl) + + + +### didUrl.did() ⇒ [CoreDID](#CoreDID) +Return a copy of the [CoreDID](#CoreDID) section of the [DIDUrl](#DIDUrl). + +**Kind**: instance method of [DIDUrl](#DIDUrl) + + +### didUrl.urlStr() ⇒ string +Return a copy of the relative DID Url as a string, including only the path, query, and fragment. + +**Kind**: instance method of [DIDUrl](#DIDUrl) + + +### didUrl.fragment() ⇒ string \| undefined +Returns a copy of the [DIDUrl](#DIDUrl) method fragment, if any. Excludes the leading '#'. + +**Kind**: instance method of [DIDUrl](#DIDUrl) + + +### didUrl.setFragment([value]) +Sets the `fragment` component of the [DIDUrl](#DIDUrl). + +**Kind**: instance method of [DIDUrl](#DIDUrl) + +| Param | Type | +| --- | --- | +| [value] | string \| undefined | + + + +### didUrl.path() ⇒ string \| undefined +Returns a copy of the [DIDUrl](#DIDUrl) path. + +**Kind**: instance method of [DIDUrl](#DIDUrl) + + +### didUrl.setPath([value]) +Sets the `path` component of the [DIDUrl](#DIDUrl). + +**Kind**: instance method of [DIDUrl](#DIDUrl) + +| Param | Type | +| --- | --- | +| [value] | string \| undefined | + + + +### didUrl.query() ⇒ string \| undefined +Returns a copy of the [DIDUrl](#DIDUrl) method query, if any. Excludes the leading '?'. + +**Kind**: instance method of [DIDUrl](#DIDUrl) + + +### didUrl.setQuery([value]) +Sets the `query` component of the [DIDUrl](#DIDUrl). + +**Kind**: instance method of [DIDUrl](#DIDUrl) + +| Param | Type | +| --- | --- | +| [value] | string \| undefined | + + + +### didUrl.join(segment) ⇒ [DIDUrl](#DIDUrl) +Append a string representing a path, query, and/or fragment, returning a new [DIDUrl](#DIDUrl). + +Must begin with a valid delimiter character: '/', '?', '#'. Overwrites the existing URL +segment and any following segments in order of path, query, then fragment. + +I.e. +- joining a path will clear the query and fragment. +- joining a query will clear the fragment. +- joining a fragment will only overwrite the fragment. + +**Kind**: instance method of [DIDUrl](#DIDUrl) + +| Param | Type | +| --- | --- | +| segment | string | + + + +### didUrl.toString() ⇒ string +Returns the [DIDUrl](#DIDUrl) as a string. + +**Kind**: instance method of [DIDUrl](#DIDUrl) + + +### didUrl.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [DIDUrl](#DIDUrl) + + +### didUrl.clone() ⇒ [DIDUrl](#DIDUrl) +Deep clones the object. + +**Kind**: instance method of [DIDUrl](#DIDUrl) + + +### DIDUrl.parse(input) ⇒ [DIDUrl](#DIDUrl) +Parses a [DIDUrl](#DIDUrl) from the input string. + +**Kind**: static method of [DIDUrl](#DIDUrl) + +| Param | Type | +| --- | --- | +| input | string | + + + +### DIDUrl.fromJSON(json) ⇒ [DIDUrl](#DIDUrl) +Deserializes an instance from a JSON object. + +**Kind**: static method of [DIDUrl](#DIDUrl) + +| Param | Type | +| --- | --- | +| json | any | + + + +## DecodedJptCredential +**Kind**: global class + +* [DecodedJptCredential](#DecodedJptCredential) + * [.clone()](#DecodedJptCredential+clone) ⇒ [DecodedJptCredential](#DecodedJptCredential) + * [.credential()](#DecodedJptCredential+credential) ⇒ [Credential](#Credential) + * [.customClaims()](#DecodedJptCredential+customClaims) ⇒ Map.<string, any> + * [.decodedJwp()](#DecodedJptCredential+decodedJwp) ⇒ [JwpIssued](#JwpIssued) + + + +### decodedJptCredential.clone() ⇒ [DecodedJptCredential](#DecodedJptCredential) +Deep clones the object. + +**Kind**: instance method of [DecodedJptCredential](#DecodedJptCredential) + + +### decodedJptCredential.credential() ⇒ [Credential](#Credential) +Returns the [Credential](#Credential) embedded into this JPT. + +**Kind**: instance method of [DecodedJptCredential](#DecodedJptCredential) + + +### decodedJptCredential.customClaims() ⇒ Map.<string, any> +Returns the custom claims parsed from the JPT. + +**Kind**: instance method of [DecodedJptCredential](#DecodedJptCredential) + + +### decodedJptCredential.decodedJwp() ⇒ [JwpIssued](#JwpIssued) +**Kind**: instance method of [DecodedJptCredential](#DecodedJptCredential) + + +## DecodedJptPresentation +**Kind**: global class + +* [DecodedJptPresentation](#DecodedJptPresentation) + * [.clone()](#DecodedJptPresentation+clone) ⇒ [DecodedJptPresentation](#DecodedJptPresentation) + * [.credential()](#DecodedJptPresentation+credential) ⇒ [Credential](#Credential) + * [.customClaims()](#DecodedJptPresentation+customClaims) ⇒ Map.<string, any> + * [.aud()](#DecodedJptPresentation+aud) ⇒ string \| undefined + + + +### decodedJptPresentation.clone() ⇒ [DecodedJptPresentation](#DecodedJptPresentation) +Deep clones the object. + +**Kind**: instance method of [DecodedJptPresentation](#DecodedJptPresentation) + + +### decodedJptPresentation.credential() ⇒ [Credential](#Credential) +Returns the [Credential](#Credential) embedded into this JPT. + +**Kind**: instance method of [DecodedJptPresentation](#DecodedJptPresentation) + + +### decodedJptPresentation.customClaims() ⇒ Map.<string, any> +Returns the custom claims parsed from the JPT. + +**Kind**: instance method of [DecodedJptPresentation](#DecodedJptPresentation) + + +### decodedJptPresentation.aud() ⇒ string \| undefined +Returns the `aud` property parsed from the JWT claims. + +**Kind**: instance method of [DecodedJptPresentation](#DecodedJptPresentation) + + +## DecodedJws +A cryptographically verified decoded token from a JWS. + +Contains the decoded headers and the raw claims. + +**Kind**: global class + +* [DecodedJws](#DecodedJws) + * [.claims()](#DecodedJws+claims) ⇒ string + * [.claimsBytes()](#DecodedJws+claimsBytes) ⇒ Uint8Array + * [.protectedHeader()](#DecodedJws+protectedHeader) ⇒ [JwsHeader](#JwsHeader) + * [.clone()](#DecodedJws+clone) ⇒ [DecodedJws](#DecodedJws) + * [.toJSON()](#DecodedJws+toJSON) ⇒ any + + + +### decodedJws.claims() ⇒ string +Returns a copy of the parsed claims represented as a string. + +# Errors +An error is thrown if the claims cannot be represented as a string. + +This error can only occur if the Token was decoded from a detached payload. + +**Kind**: instance method of [DecodedJws](#DecodedJws) + + +### decodedJws.claimsBytes() ⇒ Uint8Array +Return a copy of the parsed claims represented as an array of bytes. + +**Kind**: instance method of [DecodedJws](#DecodedJws) + + +### decodedJws.protectedHeader() ⇒ [JwsHeader](#JwsHeader) +Returns a copy of the protected header. + +**Kind**: instance method of [DecodedJws](#DecodedJws) + + +### decodedJws.clone() ⇒ [DecodedJws](#DecodedJws) +Deep clones the object. + +**Kind**: instance method of [DecodedJws](#DecodedJws) + + +### decodedJws.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [DecodedJws](#DecodedJws) + + +## DecodedJwtCredential +A cryptographically verified and decoded Credential. + +Note that having an instance of this type only means the JWS it was constructed from was verified. +It does not imply anything about a potentially present proof property on the credential itself. + +**Kind**: global class + +* [DecodedJwtCredential](#DecodedJwtCredential) + * [.credential()](#DecodedJwtCredential+credential) ⇒ [Credential](#Credential) + * [.protectedHeader()](#DecodedJwtCredential+protectedHeader) ⇒ [JwsHeader](#JwsHeader) + * [.customClaims()](#DecodedJwtCredential+customClaims) ⇒ Record.<string, any> \| undefined + * [.intoCredential()](#DecodedJwtCredential+intoCredential) ⇒ [Credential](#Credential) + + + +### decodedJwtCredential.credential() ⇒ [Credential](#Credential) +Returns a copy of the credential parsed to the [Verifiable Credentials Data model](https://www.w3.org/TR/vc-data-model/). + +**Kind**: instance method of [DecodedJwtCredential](#DecodedJwtCredential) + + +### decodedJwtCredential.protectedHeader() ⇒ [JwsHeader](#JwsHeader) +Returns a copy of the protected header parsed from the decoded JWS. + +**Kind**: instance method of [DecodedJwtCredential](#DecodedJwtCredential) + + +### decodedJwtCredential.customClaims() ⇒ Record.<string, any> \| undefined +The custom claims parsed from the JWT. + +**Kind**: instance method of [DecodedJwtCredential](#DecodedJwtCredential) + + +### decodedJwtCredential.intoCredential() ⇒ [Credential](#Credential) +Consumes the object and returns the decoded credential. + +### Warning + +This destroys the [DecodedJwtCredential](#DecodedJwtCredential) object. + +**Kind**: instance method of [DecodedJwtCredential](#DecodedJwtCredential) + + +## DecodedJwtPresentation +A cryptographically verified and decoded presentation. + +Note that having an instance of this type only means the JWS it was constructed from was verified. +It does not imply anything about a potentially present proof property on the presentation itself. + +**Kind**: global class + +* [DecodedJwtPresentation](#DecodedJwtPresentation) + * [.presentation()](#DecodedJwtPresentation+presentation) ⇒ [Presentation](#Presentation) + * [.protectedHeader()](#DecodedJwtPresentation+protectedHeader) ⇒ [JwsHeader](#JwsHeader) + * [.intoPresentation()](#DecodedJwtPresentation+intoPresentation) ⇒ [Presentation](#Presentation) + * [.expirationDate()](#DecodedJwtPresentation+expirationDate) ⇒ [Timestamp](#Timestamp) \| undefined + * [.issuanceDate()](#DecodedJwtPresentation+issuanceDate) ⇒ [Timestamp](#Timestamp) \| undefined + * [.audience()](#DecodedJwtPresentation+audience) ⇒ string \| undefined + * [.customClaims()](#DecodedJwtPresentation+customClaims) ⇒ Record.<string, any> \| undefined + + + +### decodedJwtPresentation.presentation() ⇒ [Presentation](#Presentation) +**Kind**: instance method of [DecodedJwtPresentation](#DecodedJwtPresentation) + + +### decodedJwtPresentation.protectedHeader() ⇒ [JwsHeader](#JwsHeader) +Returns a copy of the protected header parsed from the decoded JWS. + +**Kind**: instance method of [DecodedJwtPresentation](#DecodedJwtPresentation) + + +### decodedJwtPresentation.intoPresentation() ⇒ [Presentation](#Presentation) +Consumes the object and returns the decoded presentation. + +### Warning +This destroys the [DecodedJwtPresentation](#DecodedJwtPresentation) object. + +**Kind**: instance method of [DecodedJwtPresentation](#DecodedJwtPresentation) + + +### decodedJwtPresentation.expirationDate() ⇒ [Timestamp](#Timestamp) \| undefined +The expiration date parsed from the JWT claims. + +**Kind**: instance method of [DecodedJwtPresentation](#DecodedJwtPresentation) + + +### decodedJwtPresentation.issuanceDate() ⇒ [Timestamp](#Timestamp) \| undefined +The issuance date parsed from the JWT claims. + +**Kind**: instance method of [DecodedJwtPresentation](#DecodedJwtPresentation) + + +### decodedJwtPresentation.audience() ⇒ string \| undefined +The `aud` property parsed from JWT claims. + +**Kind**: instance method of [DecodedJwtPresentation](#DecodedJwtPresentation) + + +### decodedJwtPresentation.customClaims() ⇒ Record.<string, any> \| undefined +The custom claims parsed from the JWT. + +**Kind**: instance method of [DecodedJwtPresentation](#DecodedJwtPresentation) + + +## Disclosure +Represents an elements constructing a disclosure. +Object properties and array elements disclosures are supported. + +See: https://www.ietf.org/archive/id/draft-ietf-oauth-selective-disclosure-jwt-07.html#name-disclosures + +**Kind**: global class + +* [Disclosure](#Disclosure) + * [new Disclosure(salt, claim_name, claim_value)](#new_Disclosure_new) + * _instance_ + * [.disclosure()](#Disclosure+disclosure) ⇒ string + * [.toEncodedString()](#Disclosure+toEncodedString) ⇒ string + * [.toString()](#Disclosure+toString) ⇒ string + * [.salt()](#Disclosure+salt) ⇒ string + * [.claimName()](#Disclosure+claimName) ⇒ string \| undefined + * [.claimValue()](#Disclosure+claimValue) ⇒ any + * [.toJSON()](#Disclosure+toJSON) ⇒ any + * _static_ + * [.parse(disclosure)](#Disclosure.parse) ⇒ [Disclosure](#Disclosure) + * [.fromJSON(json)](#Disclosure.fromJSON) ⇒ [Disclosure](#Disclosure) + + + +### new Disclosure(salt, claim_name, claim_value) + +| Param | Type | +| --- | --- | +| salt | string | +| claim_name | string \| undefined | +| claim_value | any | + + + +### disclosure.disclosure() ⇒ string +Returns a copy of the base64url-encoded string. + +**Kind**: instance method of [Disclosure](#Disclosure) + + +### disclosure.toEncodedString() ⇒ string +Returns a copy of the base64url-encoded string. + +**Kind**: instance method of [Disclosure](#Disclosure) + + +### disclosure.toString() ⇒ string +Returns a copy of the base64url-encoded string. + +**Kind**: instance method of [Disclosure](#Disclosure) + + +### disclosure.salt() ⇒ string +Returns a copy of the salt value. + +**Kind**: instance method of [Disclosure](#Disclosure) + + +### disclosure.claimName() ⇒ string \| undefined +Returns a copy of the claim name, optional for array elements. + +**Kind**: instance method of [Disclosure](#Disclosure) + + +### disclosure.claimValue() ⇒ any +Returns a copy of the claim Value which can be of any type. + +**Kind**: instance method of [Disclosure](#Disclosure) + + +### disclosure.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [Disclosure](#Disclosure) + + +### Disclosure.parse(disclosure) ⇒ [Disclosure](#Disclosure) +Parses a Base64 encoded disclosure into a `Disclosure`. + +## Error + +Returns an `InvalidDisclosure` if input is not a valid disclosure. + +**Kind**: static method of [Disclosure](#Disclosure) + +| Param | Type | +| --- | --- | +| disclosure | string | + + + +### Disclosure.fromJSON(json) ⇒ [Disclosure](#Disclosure) +Deserializes an instance from a JSON object. + +**Kind**: static method of [Disclosure](#Disclosure) + +| Param | Type | +| --- | --- | +| json | any | + + + +## DomainLinkageConfiguration +DID Configuration Resource which contains Domain Linkage Credentials. +It can be placed in an origin's `.well-known` directory to prove linkage between the origin and a DID. +See: + +Note: +- Only the [JSON Web Token Proof Format](https://identity.foundation/.well-known/resources/did-configuration/#json-web-token-proof-format) + +**Kind**: global class + +* [DomainLinkageConfiguration](#DomainLinkageConfiguration) + * [new DomainLinkageConfiguration(linkedDids)](#new_DomainLinkageConfiguration_new) + * _instance_ + * [.linkedDids()](#DomainLinkageConfiguration+linkedDids) ⇒ [Array.<Jwt>](#Jwt) + * [.issuers()](#DomainLinkageConfiguration+issuers) ⇒ [Array.<CoreDID>](#CoreDID) + * [.toJSON()](#DomainLinkageConfiguration+toJSON) ⇒ any + * [.clone()](#DomainLinkageConfiguration+clone) ⇒ [DomainLinkageConfiguration](#DomainLinkageConfiguration) + * _static_ + * [.fromJSON(json)](#DomainLinkageConfiguration.fromJSON) ⇒ [DomainLinkageConfiguration](#DomainLinkageConfiguration) + + + +### new DomainLinkageConfiguration(linkedDids) +Constructs a new [DomainLinkageConfiguration](#DomainLinkageConfiguration). + + +| Param | Type | +| --- | --- | +| linkedDids | [Array.<Jwt>](#Jwt) | + + + +### domainLinkageConfiguration.linkedDids() ⇒ [Array.<Jwt>](#Jwt) +List of the Domain Linkage Credentials. + +**Kind**: instance method of [DomainLinkageConfiguration](#DomainLinkageConfiguration) + + +### domainLinkageConfiguration.issuers() ⇒ [Array.<CoreDID>](#CoreDID) +List of the issuers of the Domain Linkage Credentials. + +**Kind**: instance method of [DomainLinkageConfiguration](#DomainLinkageConfiguration) + + +### domainLinkageConfiguration.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [DomainLinkageConfiguration](#DomainLinkageConfiguration) + + +### domainLinkageConfiguration.clone() ⇒ [DomainLinkageConfiguration](#DomainLinkageConfiguration) +Deep clones the object. + +**Kind**: instance method of [DomainLinkageConfiguration](#DomainLinkageConfiguration) + + +### DomainLinkageConfiguration.fromJSON(json) ⇒ [DomainLinkageConfiguration](#DomainLinkageConfiguration) +Deserializes an instance from a JSON object. + +**Kind**: static method of [DomainLinkageConfiguration](#DomainLinkageConfiguration) + +| Param | Type | +| --- | --- | +| json | any | + + + +## Duration +A span of time. + +**Kind**: global class + +* [Duration](#Duration) + * _instance_ + * [.toJSON()](#Duration+toJSON) ⇒ any + * _static_ + * [.seconds(seconds)](#Duration.seconds) ⇒ [Duration](#Duration) + * [.minutes(minutes)](#Duration.minutes) ⇒ [Duration](#Duration) + * [.hours(hours)](#Duration.hours) ⇒ [Duration](#Duration) + * [.days(days)](#Duration.days) ⇒ [Duration](#Duration) + * [.weeks(weeks)](#Duration.weeks) ⇒ [Duration](#Duration) + * [.fromJSON(json)](#Duration.fromJSON) ⇒ [Duration](#Duration) + + + +### duration.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [Duration](#Duration) + + +### Duration.seconds(seconds) ⇒ [Duration](#Duration) +Create a new [Duration](#Duration) with the given number of seconds. + +**Kind**: static method of [Duration](#Duration) + +| Param | Type | +| --- | --- | +| seconds | number | + + + +### Duration.minutes(minutes) ⇒ [Duration](#Duration) +Create a new [Duration](#Duration) with the given number of minutes. + +**Kind**: static method of [Duration](#Duration) + +| Param | Type | +| --- | --- | +| minutes | number | + + + +### Duration.hours(hours) ⇒ [Duration](#Duration) +Create a new [Duration](#Duration) with the given number of hours. + +**Kind**: static method of [Duration](#Duration) + +| Param | Type | +| --- | --- | +| hours | number | + + + +### Duration.days(days) ⇒ [Duration](#Duration) +Create a new [Duration](#Duration) with the given number of days. + +**Kind**: static method of [Duration](#Duration) + +| Param | Type | +| --- | --- | +| days | number | + + + +### Duration.weeks(weeks) ⇒ [Duration](#Duration) +Create a new [Duration](#Duration) with the given number of weeks. + +**Kind**: static method of [Duration](#Duration) + +| Param | Type | +| --- | --- | +| weeks | number | + + + +### Duration.fromJSON(json) ⇒ [Duration](#Duration) +Deserializes an instance from a JSON object. + +**Kind**: static method of [Duration](#Duration) + +| Param | Type | +| --- | --- | +| json | any | + + + +## EdDSAJwsVerifier +An implementor of `IJwsVerifier` that can handle the +`EdDSA` algorithm. + +**Kind**: global class + +* [EdDSAJwsVerifier](#EdDSAJwsVerifier) + * [new EdDSAJwsVerifier()](#new_EdDSAJwsVerifier_new) + * [.verify(alg, signingInput, decodedSignature, publicKey)](#EdDSAJwsVerifier+verify) + + + +### new EdDSAJwsVerifier() +Constructs an EdDSAJwsVerifier. + + + +### edDSAJwsVerifier.verify(alg, signingInput, decodedSignature, publicKey) +Verify a JWS signature secured with the `EdDSA` algorithm. +Only the `Ed25519` curve is supported for now. + +This function is useful when one is building an `IJwsVerifier` that extends the default provided by +the IOTA Identity Framework. + +# Warning + +This function does not check whether `alg = EdDSA` in the protected header. Callers are expected to assert this +prior to calling the function. + +**Kind**: instance method of [EdDSAJwsVerifier](#EdDSAJwsVerifier) + +| Param | Type | +| --- | --- | +| alg | JwsAlgorithm | +| signingInput | Uint8Array | +| decodedSignature | Uint8Array | +| publicKey | [Jwk](#Jwk) | + + + +## IotaDID +A DID conforming to the IOTA DID method specification. + +**Kind**: global class + +* [IotaDID](#IotaDID) + * [new IotaDID(bytes, network)](#new_IotaDID_new) + * _instance_ + * [.network()](#IotaDID+network) ⇒ string + * [.tag()](#IotaDID+tag) ⇒ string + * [.toCoreDid()](#IotaDID+toCoreDid) ⇒ [CoreDID](#CoreDID) + * [.scheme()](#IotaDID+scheme) ⇒ string + * [.authority()](#IotaDID+authority) ⇒ string + * [.method()](#IotaDID+method) ⇒ string + * [.methodId()](#IotaDID+methodId) ⇒ string + * [.join(segment)](#IotaDID+join) ⇒ [DIDUrl](#DIDUrl) + * [.toUrl()](#IotaDID+toUrl) ⇒ [DIDUrl](#DIDUrl) + * [.toAliasId()](#IotaDID+toAliasId) ⇒ string + * [.intoUrl()](#IotaDID+intoUrl) ⇒ [DIDUrl](#DIDUrl) + * [.toString()](#IotaDID+toString) ⇒ string + * [.toJSON()](#IotaDID+toJSON) ⇒ any + * [.clone()](#IotaDID+clone) ⇒ [IotaDID](#IotaDID) + * _static_ + * [.METHOD](#IotaDID.METHOD) ⇒ string + * [.DEFAULT_NETWORK](#IotaDID.DEFAULT_NETWORK) ⇒ string + * [.fromAliasId(aliasId, network)](#IotaDID.fromAliasId) ⇒ [IotaDID](#IotaDID) + * [.placeholder(network)](#IotaDID.placeholder) ⇒ [IotaDID](#IotaDID) + * [.parse(input)](#IotaDID.parse) ⇒ [IotaDID](#IotaDID) + * [.fromJSON(json)](#IotaDID.fromJSON) ⇒ [IotaDID](#IotaDID) + + + +### new IotaDID(bytes, network) +Constructs a new [IotaDID](#IotaDID) from a byte representation of the tag and the given +network name. + +See also [placeholder](#IotaDID.placeholder). + + +| Param | Type | +| --- | --- | +| bytes | Uint8Array | +| network | string | + + + +### did.network() ⇒ string +Returns the Tangle network name of the [IotaDID](#IotaDID). + +**Kind**: instance method of [IotaDID](#IotaDID) + + +### did.tag() ⇒ string +Returns a copy of the unique tag of the [IotaDID](#IotaDID). + +**Kind**: instance method of [IotaDID](#IotaDID) + + +### did.toCoreDid() ⇒ [CoreDID](#CoreDID) +Returns the DID represented as a [CoreDID](#CoreDID). + +**Kind**: instance method of [IotaDID](#IotaDID) + + +### did.scheme() ⇒ string +Returns the `DID` scheme. + +E.g. +- `"did:example:12345678" -> "did"` +- `"did:iota:main:12345678" -> "did"` + +**Kind**: instance method of [IotaDID](#IotaDID) + + +### did.authority() ⇒ string +Returns the `DID` authority: the method name and method-id. + +E.g. +- `"did:example:12345678" -> "example:12345678"` +- `"did:iota:main:12345678" -> "iota:main:12345678"` + +**Kind**: instance method of [IotaDID](#IotaDID) + + +### did.method() ⇒ string +Returns the `DID` method name. + +E.g. +- `"did:example:12345678" -> "example"` +- `"did:iota:main:12345678" -> "iota"` + +**Kind**: instance method of [IotaDID](#IotaDID) + + +### did.methodId() ⇒ string +Returns the `DID` method-specific ID. + +E.g. +- `"did:example:12345678" -> "12345678"` +- `"did:iota:main:12345678" -> "main:12345678"` + +**Kind**: instance method of [IotaDID](#IotaDID) + + +### did.join(segment) ⇒ [DIDUrl](#DIDUrl) +Construct a new [DIDUrl](#DIDUrl) by joining with a relative DID Url string. + +**Kind**: instance method of [IotaDID](#IotaDID) + +| Param | Type | +| --- | --- | +| segment | string | + + + +### did.toUrl() ⇒ [DIDUrl](#DIDUrl) +Clones the `DID` into a [DIDUrl](#DIDUrl). + +**Kind**: instance method of [IotaDID](#IotaDID) + + +### did.toAliasId() ⇒ string +Returns the hex-encoded AliasId with a '0x' prefix, from the DID tag. + +**Kind**: instance method of [IotaDID](#IotaDID) + + +### did.intoUrl() ⇒ [DIDUrl](#DIDUrl) +Converts the `DID` into a [DIDUrl](#DIDUrl), consuming it. + +**Kind**: instance method of [IotaDID](#IotaDID) + + +### did.toString() ⇒ string +Returns the `DID` as a string. + +**Kind**: instance method of [IotaDID](#IotaDID) + + +### did.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [IotaDID](#IotaDID) + + +### did.clone() ⇒ [IotaDID](#IotaDID) +Deep clones the object. + +**Kind**: instance method of [IotaDID](#IotaDID) + + +### IotaDID.METHOD ⇒ string +The IOTA DID method name (`"iota"`). + +**Kind**: static property of [IotaDID](#IotaDID) + + +### IotaDID.DEFAULT\_NETWORK ⇒ string +The default Tangle network (`"iota"`). + +**Kind**: static property of [IotaDID](#IotaDID) + + +### IotaDID.fromAliasId(aliasId, network) ⇒ [IotaDID](#IotaDID) +Constructs a new [IotaDID](#IotaDID) from a hex representation of an Alias Id and the given +network name. + +**Kind**: static method of [IotaDID](#IotaDID) + +| Param | Type | +| --- | --- | +| aliasId | string | +| network | string | + + + +### IotaDID.placeholder(network) ⇒ [IotaDID](#IotaDID) +Creates a new placeholder [IotaDID](#IotaDID) with the given network name. + +E.g. `did:iota:smr:0x0000000000000000000000000000000000000000000000000000000000000000`. + +**Kind**: static method of [IotaDID](#IotaDID) + +| Param | Type | +| --- | --- | +| network | string | + + + +### IotaDID.parse(input) ⇒ [IotaDID](#IotaDID) +Parses a [IotaDID](#IotaDID) from the input string. + +**Kind**: static method of [IotaDID](#IotaDID) + +| Param | Type | +| --- | --- | +| input | string | + + + +### IotaDID.fromJSON(json) ⇒ [IotaDID](#IotaDID) +Deserializes an instance from a JSON object. + +**Kind**: static method of [IotaDID](#IotaDID) + +| Param | Type | +| --- | --- | +| json | any | + + + +## IotaDocument +A DID Document adhering to the IOTA DID method specification. + +Note: All methods that involve reading from this class may potentially raise an error +if the object is being concurrently modified. + +**Kind**: global class + +* [IotaDocument](#IotaDocument) + * [new IotaDocument(network)](#new_IotaDocument_new) + * _instance_ + * [.id()](#IotaDocument+id) ⇒ [IotaDID](#IotaDID) + * [.controller()](#IotaDocument+controller) ⇒ [Array.<IotaDID>](#IotaDID) + * [.setController(controller)](#IotaDocument+setController) + * [.alsoKnownAs()](#IotaDocument+alsoKnownAs) ⇒ Array.<string> + * [.setAlsoKnownAs(urls)](#IotaDocument+setAlsoKnownAs) + * [.properties()](#IotaDocument+properties) ⇒ Map.<string, any> + * [.setPropertyUnchecked(key, value)](#IotaDocument+setPropertyUnchecked) + * [.service()](#IotaDocument+service) ⇒ [Array.<Service>](#Service) + * [.insertService(service)](#IotaDocument+insertService) + * [.removeService(did)](#IotaDocument+removeService) ⇒ [Service](#Service) \| undefined + * [.resolveService(query)](#IotaDocument+resolveService) ⇒ [Service](#Service) \| undefined + * [.methods([scope])](#IotaDocument+methods) ⇒ [Array.<VerificationMethod>](#VerificationMethod) + * [.insertMethod(method, scope)](#IotaDocument+insertMethod) + * [.removeMethod(did)](#IotaDocument+removeMethod) ⇒ [VerificationMethod](#VerificationMethod) \| undefined + * [.resolveMethod(query, [scope])](#IotaDocument+resolveMethod) ⇒ [VerificationMethod](#VerificationMethod) \| undefined + * [.attachMethodRelationship(didUrl, relationship)](#IotaDocument+attachMethodRelationship) ⇒ boolean + * [.detachMethodRelationship(didUrl, relationship)](#IotaDocument+detachMethodRelationship) ⇒ boolean + * [.verifyJws(jws, options, signatureVerifier, [detachedPayload])](#IotaDocument+verifyJws) ⇒ [DecodedJws](#DecodedJws) + * [.pack()](#IotaDocument+pack) ⇒ Uint8Array + * [.packWithEncoding(encoding)](#IotaDocument+packWithEncoding) ⇒ Uint8Array + * [.metadata()](#IotaDocument+metadata) ⇒ [IotaDocumentMetadata](#IotaDocumentMetadata) + * [.metadataCreated()](#IotaDocument+metadataCreated) ⇒ [Timestamp](#Timestamp) \| undefined + * [.setMetadataCreated(timestamp)](#IotaDocument+setMetadataCreated) + * [.metadataUpdated()](#IotaDocument+metadataUpdated) ⇒ [Timestamp](#Timestamp) \| undefined + * [.setMetadataUpdated(timestamp)](#IotaDocument+setMetadataUpdated) + * [.metadataDeactivated()](#IotaDocument+metadataDeactivated) ⇒ boolean \| undefined + * [.setMetadataDeactivated([deactivated])](#IotaDocument+setMetadataDeactivated) + * [.metadataStateControllerAddress()](#IotaDocument+metadataStateControllerAddress) ⇒ string \| undefined + * [.metadataGovernorAddress()](#IotaDocument+metadataGovernorAddress) ⇒ string \| undefined + * [.setMetadataPropertyUnchecked(key, value)](#IotaDocument+setMetadataPropertyUnchecked) + * [.revokeCredentials(serviceQuery, indices)](#IotaDocument+revokeCredentials) + * [.unrevokeCredentials(serviceQuery, indices)](#IotaDocument+unrevokeCredentials) + * [.clone()](#IotaDocument+clone) ⇒ [IotaDocument](#IotaDocument) + * [._shallowCloneInternal()](#IotaDocument+_shallowCloneInternal) ⇒ [IotaDocument](#IotaDocument) + * [._strongCountInternal()](#IotaDocument+_strongCountInternal) ⇒ number + * [.toJSON()](#IotaDocument+toJSON) ⇒ any + * [.toCoreDocument()](#IotaDocument+toCoreDocument) ⇒ [CoreDocument](#CoreDocument) + * [.generateMethod(storage, keyType, alg, fragment, scope)](#IotaDocument+generateMethod) ⇒ Promise.<string> + * [.purgeMethod(storage, id)](#IotaDocument+purgeMethod) ⇒ Promise.<void> + * ~~[.createJwt(storage, fragment, payload, options)](#IotaDocument+createJwt) ⇒ [Promise.<Jws>](#Jws)~~ + * [.createJws(storage, fragment, payload, options)](#IotaDocument+createJws) ⇒ [Promise.<Jws>](#Jws) + * [.createCredentialJwt(storage, fragment, credential, options, [custom_claims])](#IotaDocument+createCredentialJwt) ⇒ [Promise.<Jwt>](#Jwt) + * [.createPresentationJwt(storage, fragment, presentation, signature_options, presentation_options)](#IotaDocument+createPresentationJwt) ⇒ [Promise.<Jwt>](#Jwt) + * [.generateMethodJwp(storage, alg, fragment, scope)](#IotaDocument+generateMethodJwp) ⇒ Promise.<string> + * [.createIssuedJwp(storage, fragment, jpt_claims, options)](#IotaDocument+createIssuedJwp) ⇒ Promise.<string> + * [.createPresentedJwp(presentation, method_id, options)](#IotaDocument+createPresentedJwp) ⇒ Promise.<string> + * [.createCredentialJpt(credential, storage, fragment, options, [custom_claims])](#IotaDocument+createCredentialJpt) ⇒ [Promise.<Jpt>](#Jpt) + * [.createPresentationJpt(presentation, method_id, options)](#IotaDocument+createPresentationJpt) ⇒ [Promise.<Jpt>](#Jpt) + * _static_ + * [.newWithId(id)](#IotaDocument.newWithId) ⇒ [IotaDocument](#IotaDocument) + * [.unpackFromOutput(did, aliasOutput, allowEmpty)](#IotaDocument.unpackFromOutput) ⇒ [IotaDocument](#IotaDocument) + * [.unpackFromBlock(network, block)](#IotaDocument.unpackFromBlock) ⇒ [Array.<IotaDocument>](#IotaDocument) + * [.fromJSON(json)](#IotaDocument.fromJSON) ⇒ [IotaDocument](#IotaDocument) + + + +### new IotaDocument(network) +Constructs an empty IOTA DID Document with a [placeholder](#IotaDID.placeholder) identifier +for the given `network`. + + +| Param | Type | +| --- | --- | +| network | string | + + + +### iotaDocument.id() ⇒ [IotaDID](#IotaDID) +Returns a copy of the DID Document `id`. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + + +### iotaDocument.controller() ⇒ [Array.<IotaDID>](#IotaDID) +Returns a copy of the list of document controllers. + +NOTE: controllers are determined by the `state_controller` unlock condition of the output +during resolution and are omitted when publishing. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + + +### iotaDocument.setController(controller) +Sets the controllers of the document. + +Note: Duplicates will be ignored. +Use `null` to remove all controllers. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| controller | [Array.<IotaDID>](#IotaDID) \| null | + + + +### iotaDocument.alsoKnownAs() ⇒ Array.<string> +Returns a copy of the document's `alsoKnownAs` set. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + + +### iotaDocument.setAlsoKnownAs(urls) +Sets the `alsoKnownAs` property in the DID document. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| urls | string \| Array.<string> \| null | + + + +### iotaDocument.properties() ⇒ Map.<string, any> +Returns a copy of the custom DID Document properties. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + + +### iotaDocument.setPropertyUnchecked(key, value) +Sets a custom property in the DID Document. +If the value is set to `null`, the custom property will be removed. + +### WARNING + +This method can overwrite existing properties like `id` and result in an invalid document. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| key | string | +| value | any | + + + +### iotaDocument.service() ⇒ [Array.<Service>](#Service) +Return a set of all [Service](#Service) in the document. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + + +### iotaDocument.insertService(service) +Add a new [Service](#Service) to the document. + +Returns `true` if the service was added. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| service | [Service](#Service) | + + + +### iotaDocument.removeService(did) ⇒ [Service](#Service) \| undefined +Remove a [Service](#Service) identified by the given [DIDUrl](#DIDUrl) from the document. + +Returns `true` if a service was removed. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| did | [DIDUrl](#DIDUrl) | + + + +### iotaDocument.resolveService(query) ⇒ [Service](#Service) \| undefined +Returns the first [Service](#Service) with an `id` property matching the provided `query`, +if present. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| query | [DIDUrl](#DIDUrl) \| string | + + + +### iotaDocument.methods([scope]) ⇒ [Array.<VerificationMethod>](#VerificationMethod) +Returns a list of all [VerificationMethod](#VerificationMethod) in the DID Document, +whose verification relationship matches `scope`. + +If `scope` is not set, a list over the **embedded** methods is returned. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| [scope] | [MethodScope](#MethodScope) \| undefined | + + + +### iotaDocument.insertMethod(method, scope) +Adds a new `method` to the document in the given `scope`. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| method | [VerificationMethod](#VerificationMethod) | +| scope | [MethodScope](#MethodScope) | + + + +### iotaDocument.removeMethod(did) ⇒ [VerificationMethod](#VerificationMethod) \| undefined +Removes all references to the specified Verification Method. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| did | [DIDUrl](#DIDUrl) | + + + +### iotaDocument.resolveMethod(query, [scope]) ⇒ [VerificationMethod](#VerificationMethod) \| undefined +Returns a copy of the first verification method with an `id` property +matching the provided `query` and the verification relationship +specified by `scope`, if present. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| query | [DIDUrl](#DIDUrl) \| string | +| [scope] | [MethodScope](#MethodScope) \| undefined | + + + +### iotaDocument.attachMethodRelationship(didUrl, relationship) ⇒ boolean +Attaches the relationship to the given method, if the method exists. + +Note: The method needs to be in the set of verification methods, +so it cannot be an embedded one. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| didUrl | [DIDUrl](#DIDUrl) | +| relationship | [MethodRelationship](#MethodRelationship) | + + + +### iotaDocument.detachMethodRelationship(didUrl, relationship) ⇒ boolean +Detaches the given relationship from the given method, if the method exists. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| didUrl | [DIDUrl](#DIDUrl) | +| relationship | [MethodRelationship](#MethodRelationship) | + + + +### iotaDocument.verifyJws(jws, options, signatureVerifier, [detachedPayload]) ⇒ [DecodedJws](#DecodedJws) +Decodes and verifies the provided JWS according to the passed `options` and `signatureVerifier`. + If no `signatureVerifier` argument is provided a default verifier will be used that is (only) capable of +verifying EdDSA signatures. + +Regardless of which options are passed the following conditions must be met in order for a verification attempt to +take place. +- The JWS must be encoded according to the JWS compact serialization. +- The `kid` value in the protected header must be an identifier of a verification method in this DID document. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| jws | [Jws](#Jws) | +| options | [JwsVerificationOptions](#JwsVerificationOptions) | +| signatureVerifier | IJwsVerifier | +| [detachedPayload] | string \| undefined | + + + +### iotaDocument.pack() ⇒ Uint8Array +Serializes the document for inclusion in an Alias Output's state metadata +with the default [StateMetadataEncoding](#StateMetadataEncoding). + +**Kind**: instance method of [IotaDocument](#IotaDocument) + + +### iotaDocument.packWithEncoding(encoding) ⇒ Uint8Array +Serializes the document for inclusion in an Alias Output's state metadata. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| encoding | [StateMetadataEncoding](#StateMetadataEncoding) | + + + +### iotaDocument.metadata() ⇒ [IotaDocumentMetadata](#IotaDocumentMetadata) +Returns a copy of the metadata associated with this document. + +NOTE: Copies all the metadata. See also `metadataCreated`, `metadataUpdated`, +`metadataPreviousMessageId`, `metadataProof` if only a subset of the metadata required. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + + +### iotaDocument.metadataCreated() ⇒ [Timestamp](#Timestamp) \| undefined +Returns a copy of the timestamp of when the DID document was created. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + + +### iotaDocument.setMetadataCreated(timestamp) +Sets the timestamp of when the DID document was created. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| timestamp | [Timestamp](#Timestamp) \| undefined | + + + +### iotaDocument.metadataUpdated() ⇒ [Timestamp](#Timestamp) \| undefined +Returns a copy of the timestamp of the last DID document update. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + + +### iotaDocument.setMetadataUpdated(timestamp) +Sets the timestamp of the last DID document update. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| timestamp | [Timestamp](#Timestamp) \| undefined | + + + +### iotaDocument.metadataDeactivated() ⇒ boolean \| undefined +Returns a copy of the deactivated status of the DID document. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + + +### iotaDocument.setMetadataDeactivated([deactivated]) +Sets the deactivated status of the DID document. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| [deactivated] | boolean \| undefined | + + + +### iotaDocument.metadataStateControllerAddress() ⇒ string \| undefined +Returns a copy of the Bech32-encoded state controller address, if present. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + + +### iotaDocument.metadataGovernorAddress() ⇒ string \| undefined +Returns a copy of the Bech32-encoded governor address, if present. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + + +### iotaDocument.setMetadataPropertyUnchecked(key, value) +Sets a custom property in the document metadata. +If the value is set to `null`, the custom property will be removed. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| key | string | +| value | any | + + + +### iotaDocument.revokeCredentials(serviceQuery, indices) +If the document has a [RevocationBitmap](#RevocationBitmap) service identified by `serviceQuery`, +revoke all specified `indices`. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| serviceQuery | [DIDUrl](#DIDUrl) \| string | +| indices | number \| Array.<number> | + + + +### iotaDocument.unrevokeCredentials(serviceQuery, indices) +If the document has a [RevocationBitmap](#RevocationBitmap) service identified by `serviceQuery`, +unrevoke all specified `indices`. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| serviceQuery | [DIDUrl](#DIDUrl) \| string | +| indices | number \| Array.<number> | + + + +### iotaDocument.clone() ⇒ [IotaDocument](#IotaDocument) +Returns a deep clone of the [IotaDocument](#IotaDocument). + +**Kind**: instance method of [IotaDocument](#IotaDocument) + + +### iotaDocument.\_shallowCloneInternal() ⇒ [IotaDocument](#IotaDocument) +### Warning +This is for internal use only. Do not rely on or call this method. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + + +### iotaDocument.\_strongCountInternal() ⇒ number +### Warning +This is for internal use only. Do not rely on or call this method. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + + +### iotaDocument.toJSON() ⇒ any +Serializes to a plain JS representation. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + + +### iotaDocument.toCoreDocument() ⇒ [CoreDocument](#CoreDocument) +Transforms the [IotaDocument](#IotaDocument) to its [CoreDocument](#CoreDocument) representation. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + + +### iotaDocument.generateMethod(storage, keyType, alg, fragment, scope) ⇒ Promise.<string> +Generate new key material in the given `storage` and insert a new verification method with the corresponding +public key material into the DID document. + +- If no fragment is given the `kid` of the generated JWK is used, if it is set, otherwise an error is returned. +- The `keyType` must be compatible with the given `storage`. `Storage`s are expected to export key type constants +for that use case. + +The fragment of the generated method is returned. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| storage | [Storage](#Storage) | +| keyType | string | +| alg | JwsAlgorithm | +| fragment | string \| undefined | +| scope | [MethodScope](#MethodScope) | + + + +### iotaDocument.purgeMethod(storage, id) ⇒ Promise.<void> +Remove the method identified by the given fragment from the document and delete the corresponding key material in +the given `storage`. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| storage | [Storage](#Storage) | +| id | [DIDUrl](#DIDUrl) | + + + +### ~~iotaDocument.createJwt(storage, fragment, payload, options) ⇒ [Promise.<Jws>](#Jws)~~ +***Deprecated*** + +Sign the `payload` according to `options` with the storage backed private key corresponding to the public key +material in the verification method identified by the given `fragment. + +Upon success a string representing a JWS encoded according to the Compact JWS Serialization format is returned. +See [RFC7515 section 3.1](https://www.rfc-editor.org/rfc/rfc7515#section-3.1). + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| storage | [Storage](#Storage) | +| fragment | string | +| payload | string | +| options | [JwsSignatureOptions](#JwsSignatureOptions) | + + + +### iotaDocument.createJws(storage, fragment, payload, options) ⇒ [Promise.<Jws>](#Jws) +Sign the `payload` according to `options` with the storage backed private key corresponding to the public key +material in the verification method identified by the given `fragment. + +Upon success a string representing a JWS encoded according to the Compact JWS Serialization format is returned. +See [RFC7515 section 3.1](https://www.rfc-editor.org/rfc/rfc7515#section-3.1). + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| storage | [Storage](#Storage) | +| fragment | string | +| payload | string | +| options | [JwsSignatureOptions](#JwsSignatureOptions) | + + + +### iotaDocument.createCredentialJwt(storage, fragment, credential, options, [custom_claims]) ⇒ [Promise.<Jwt>](#Jwt) +Produces a JWS where the payload is produced from the given `credential` +in accordance with [VC Data Model v1.1](https://www.w3.org/TR/vc-data-model/#json-web-token). + +Unless the `kid` is explicitly set in the options, the `kid` in the protected header is the `id` +of the method identified by `fragment` and the JWS signature will be produced by the corresponding +private key backed by the `storage` in accordance with the passed `options`. + +The `custom_claims` can be used to set additional claims on the resulting JWT. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| storage | [Storage](#Storage) | +| fragment | string | +| credential | [Credential](#Credential) | +| options | [JwsSignatureOptions](#JwsSignatureOptions) | +| [custom_claims] | Record.<string, any> \| undefined | + + + +### iotaDocument.createPresentationJwt(storage, fragment, presentation, signature_options, presentation_options) ⇒ [Promise.<Jwt>](#Jwt) +Produces a JWT where the payload is produced from the given presentation. +in accordance with [VC Data Model v1.1](https://www.w3.org/TR/vc-data-model/#json-web-token). + +Unless the `kid` is explicitly set in the options, the `kid` in the protected header is the `id` +of the method identified by `fragment` and the JWS signature will be produced by the corresponding +private key backed by the `storage` in accordance with the passed `options`. + +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| storage | [Storage](#Storage) | +| fragment | string | +| presentation | [Presentation](#Presentation) | +| signature_options | [JwsSignatureOptions](#JwsSignatureOptions) | +| presentation_options | [JwtPresentationOptions](#JwtPresentationOptions) | + + + +### iotaDocument.generateMethodJwp(storage, alg, fragment, scope) ⇒ Promise.<string> +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| storage | [Storage](#Storage) | +| alg | [ProofAlgorithm](#ProofAlgorithm) | +| fragment | string \| undefined | +| scope | [MethodScope](#MethodScope) | + + + +### iotaDocument.createIssuedJwp(storage, fragment, jpt_claims, options) ⇒ Promise.<string> +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| storage | [Storage](#Storage) | +| fragment | string | +| jpt_claims | JptClaims | +| options | [JwpCredentialOptions](#JwpCredentialOptions) | + + + +### iotaDocument.createPresentedJwp(presentation, method_id, options) ⇒ Promise.<string> +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| presentation | [SelectiveDisclosurePresentation](#SelectiveDisclosurePresentation) | +| method_id | string | +| options | [JwpPresentationOptions](#JwpPresentationOptions) | + + + +### iotaDocument.createCredentialJpt(credential, storage, fragment, options, [custom_claims]) ⇒ [Promise.<Jpt>](#Jpt) +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| credential | [Credential](#Credential) | +| storage | [Storage](#Storage) | +| fragment | string | +| options | [JwpCredentialOptions](#JwpCredentialOptions) | +| [custom_claims] | Map.<string, any> \| undefined | + + + +### iotaDocument.createPresentationJpt(presentation, method_id, options) ⇒ [Promise.<Jpt>](#Jpt) +**Kind**: instance method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| presentation | [SelectiveDisclosurePresentation](#SelectiveDisclosurePresentation) | +| method_id | string | +| options | [JwpPresentationOptions](#JwpPresentationOptions) | + + + +### IotaDocument.newWithId(id) ⇒ [IotaDocument](#IotaDocument) +Constructs an empty DID Document with the given identifier. + +**Kind**: static method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| id | [IotaDID](#IotaDID) | + + + +### IotaDocument.unpackFromOutput(did, aliasOutput, allowEmpty) ⇒ [IotaDocument](#IotaDocument) +Deserializes the document from an Alias Output. + +If `allowEmpty` is true, this will return an empty DID document marked as `deactivated` +if `stateMetadata` is empty. + +The `tokenSupply` must be equal to the token supply of the network the DID is associated with. + +NOTE: `did` is required since it is omitted from the serialized DID Document and +cannot be inferred from the state metadata. It also indicates the network, which is not +encoded in the `AliasId` alone. + +**Kind**: static method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| did | [IotaDID](#IotaDID) | +| aliasOutput | AliasOutputBuilderParams | +| allowEmpty | boolean | + + + +### IotaDocument.unpackFromBlock(network, block) ⇒ [Array.<IotaDocument>](#IotaDocument) +Returns all DID documents of the Alias Outputs contained in the block's transaction payload +outputs, if any. + +Errors if any Alias Output does not contain a valid or empty DID Document. + +**Kind**: static method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| network | string | +| block | Block | + + + +### IotaDocument.fromJSON(json) ⇒ [IotaDocument](#IotaDocument) +Deserializes an instance from a plain JS representation. + +**Kind**: static method of [IotaDocument](#IotaDocument) + +| Param | Type | +| --- | --- | +| json | any | + + + +## IotaDocumentMetadata +Additional attributes related to an IOTA DID Document. + +**Kind**: global class + +* [IotaDocumentMetadata](#IotaDocumentMetadata) + * _instance_ + * [.created()](#IotaDocumentMetadata+created) ⇒ [Timestamp](#Timestamp) \| undefined + * [.updated()](#IotaDocumentMetadata+updated) ⇒ [Timestamp](#Timestamp) \| undefined + * [.deactivated()](#IotaDocumentMetadata+deactivated) ⇒ boolean \| undefined + * [.stateControllerAddress()](#IotaDocumentMetadata+stateControllerAddress) ⇒ string \| undefined + * [.governorAddress()](#IotaDocumentMetadata+governorAddress) ⇒ string \| undefined + * [.properties()](#IotaDocumentMetadata+properties) ⇒ Map.<string, any> + * [.toJSON()](#IotaDocumentMetadata+toJSON) ⇒ any + * [.clone()](#IotaDocumentMetadata+clone) ⇒ [IotaDocumentMetadata](#IotaDocumentMetadata) + * _static_ + * [.fromJSON(json)](#IotaDocumentMetadata.fromJSON) ⇒ [IotaDocumentMetadata](#IotaDocumentMetadata) + + + +### iotaDocumentMetadata.created() ⇒ [Timestamp](#Timestamp) \| undefined +Returns a copy of the timestamp of when the DID document was created. + +**Kind**: instance method of [IotaDocumentMetadata](#IotaDocumentMetadata) + + +### iotaDocumentMetadata.updated() ⇒ [Timestamp](#Timestamp) \| undefined +Returns a copy of the timestamp of the last DID document update. + +**Kind**: instance method of [IotaDocumentMetadata](#IotaDocumentMetadata) + + +### iotaDocumentMetadata.deactivated() ⇒ boolean \| undefined +Returns a copy of the deactivated status of the DID document. + +**Kind**: instance method of [IotaDocumentMetadata](#IotaDocumentMetadata) + + +### iotaDocumentMetadata.stateControllerAddress() ⇒ string \| undefined +Returns a copy of the Bech32-encoded state controller address, if present. + +**Kind**: instance method of [IotaDocumentMetadata](#IotaDocumentMetadata) + + +### iotaDocumentMetadata.governorAddress() ⇒ string \| undefined +Returns a copy of the Bech32-encoded governor address, if present. + +**Kind**: instance method of [IotaDocumentMetadata](#IotaDocumentMetadata) + + +### iotaDocumentMetadata.properties() ⇒ Map.<string, any> +Returns a copy of the custom metadata properties. + +**Kind**: instance method of [IotaDocumentMetadata](#IotaDocumentMetadata) + + +### iotaDocumentMetadata.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [IotaDocumentMetadata](#IotaDocumentMetadata) + + +### iotaDocumentMetadata.clone() ⇒ [IotaDocumentMetadata](#IotaDocumentMetadata) +Deep clones the object. + +**Kind**: instance method of [IotaDocumentMetadata](#IotaDocumentMetadata) + + +### IotaDocumentMetadata.fromJSON(json) ⇒ [IotaDocumentMetadata](#IotaDocumentMetadata) +Deserializes an instance from a JSON object. + +**Kind**: static method of [IotaDocumentMetadata](#IotaDocumentMetadata) + +| Param | Type | +| --- | --- | +| json | any | + + + +## IotaIdentityClientExt +An extension interface that provides helper functions for publication +and resolution of DID documents in Alias Outputs. + +**Kind**: global class + +* [IotaIdentityClientExt](#IotaIdentityClientExt) + * [.newDidOutput(client, address, document, [rentStructure])](#IotaIdentityClientExt.newDidOutput) ⇒ Promise.<AliasOutputBuilderParams> + * [.updateDidOutput(client, document)](#IotaIdentityClientExt.updateDidOutput) ⇒ Promise.<AliasOutputBuilderParams> + * [.deactivateDidOutput(client, did)](#IotaIdentityClientExt.deactivateDidOutput) ⇒ Promise.<AliasOutputBuilderParams> + * [.resolveDid(client, did)](#IotaIdentityClientExt.resolveDid) ⇒ [Promise.<IotaDocument>](#IotaDocument) + * [.resolveDidOutput(client, did)](#IotaIdentityClientExt.resolveDidOutput) ⇒ Promise.<AliasOutputBuilderParams> + + + +### IotaIdentityClientExt.newDidOutput(client, address, document, [rentStructure]) ⇒ Promise.<AliasOutputBuilderParams> +Create a DID with a new Alias Output containing the given `document`. + +The `address` will be set as the state controller and governor unlock conditions. +The minimum required token deposit amount will be set according to the given +`rent_structure`, which will be fetched from the node if not provided. +The returned Alias Output can be further customised before publication, if desired. + +NOTE: this does *not* publish the Alias Output. + +**Kind**: static method of [IotaIdentityClientExt](#IotaIdentityClientExt) + +| Param | Type | +| --- | --- | +| client | IIotaIdentityClient | +| address | Address | +| document | [IotaDocument](#IotaDocument) | +| [rentStructure] | IRent \| undefined | + + + +### IotaIdentityClientExt.updateDidOutput(client, document) ⇒ Promise.<AliasOutputBuilderParams> +Fetches the associated Alias Output and updates it with `document` in its state metadata. +The storage deposit on the output is left unchanged. If the size of the document increased, +the amount should be increased manually. + +NOTE: this does *not* publish the updated Alias Output. + +**Kind**: static method of [IotaIdentityClientExt](#IotaIdentityClientExt) + +| Param | Type | +| --- | --- | +| client | IIotaIdentityClient | +| document | [IotaDocument](#IotaDocument) | + + + +### IotaIdentityClientExt.deactivateDidOutput(client, did) ⇒ Promise.<AliasOutputBuilderParams> +Removes the DID document from the state metadata of its Alias Output, +effectively deactivating it. The storage deposit on the output is left unchanged, +and should be reallocated manually. + +Deactivating does not destroy the output. Hence, it can be re-activated by publishing +an update containing a DID document. + +NOTE: this does *not* publish the updated Alias Output. + +**Kind**: static method of [IotaIdentityClientExt](#IotaIdentityClientExt) + +| Param | Type | +| --- | --- | +| client | IIotaIdentityClient | +| did | [IotaDID](#IotaDID) | + + + +### IotaIdentityClientExt.resolveDid(client, did) ⇒ [Promise.<IotaDocument>](#IotaDocument) +Resolve a [IotaDocument](#IotaDocument). Returns an empty, deactivated document if the state metadata +of the Alias Output is empty. + +**Kind**: static method of [IotaIdentityClientExt](#IotaIdentityClientExt) + +| Param | Type | +| --- | --- | +| client | IIotaIdentityClient | +| did | [IotaDID](#IotaDID) | + + + +### IotaIdentityClientExt.resolveDidOutput(client, did) ⇒ Promise.<AliasOutputBuilderParams> +Fetches the `IAliasOutput` associated with the given DID. + +**Kind**: static method of [IotaIdentityClientExt](#IotaIdentityClientExt) + +| Param | Type | +| --- | --- | +| client | IIotaIdentityClient | +| did | [IotaDID](#IotaDID) | + + + +## IssuerProtectedHeader +**Kind**: global class + +* [IssuerProtectedHeader](#IssuerProtectedHeader) + * [.typ](#IssuerProtectedHeader+typ) ⇒ string \| undefined + * [.typ](#IssuerProtectedHeader+typ) + * [.alg](#IssuerProtectedHeader+alg) ⇒ [ProofAlgorithm](#ProofAlgorithm) + * [.alg](#IssuerProtectedHeader+alg) + * [.kid](#IssuerProtectedHeader+kid) ⇒ string \| undefined + * [.kid](#IssuerProtectedHeader+kid) + * [.cid](#IssuerProtectedHeader+cid) ⇒ string \| undefined + * [.cid](#IssuerProtectedHeader+cid) + * [.claims()](#IssuerProtectedHeader+claims) ⇒ Array.<string> + + + +### issuerProtectedHeader.typ ⇒ string \| undefined +JWP type (JPT). + +**Kind**: instance property of [IssuerProtectedHeader](#IssuerProtectedHeader) + + +### issuerProtectedHeader.typ +JWP type (JPT). + +**Kind**: instance property of [IssuerProtectedHeader](#IssuerProtectedHeader) + +| Param | Type | +| --- | --- | +| [arg0] | string \| undefined | + + + +### issuerProtectedHeader.alg ⇒ [ProofAlgorithm](#ProofAlgorithm) +Algorithm used for the JWP. + +**Kind**: instance property of [IssuerProtectedHeader](#IssuerProtectedHeader) + + +### issuerProtectedHeader.alg +Algorithm used for the JWP. + +**Kind**: instance property of [IssuerProtectedHeader](#IssuerProtectedHeader) + +| Param | Type | +| --- | --- | +| arg0 | [ProofAlgorithm](#ProofAlgorithm) | + + + +### issuerProtectedHeader.kid ⇒ string \| undefined +ID for the key used for the JWP. + +**Kind**: instance property of [IssuerProtectedHeader](#IssuerProtectedHeader) + + +### issuerProtectedHeader.kid +ID for the key used for the JWP. + +**Kind**: instance property of [IssuerProtectedHeader](#IssuerProtectedHeader) + +| Param | Type | +| --- | --- | +| [arg0] | string \| undefined | + + + +### issuerProtectedHeader.cid ⇒ string \| undefined +Not handled for now. Will be used in the future to resolve external claims + +**Kind**: instance property of [IssuerProtectedHeader](#IssuerProtectedHeader) + + +### issuerProtectedHeader.cid +Not handled for now. Will be used in the future to resolve external claims + +**Kind**: instance property of [IssuerProtectedHeader](#IssuerProtectedHeader) + +| Param | Type | +| --- | --- | +| [arg0] | string \| undefined | + + + +### issuerProtectedHeader.claims() ⇒ Array.<string> +**Kind**: instance method of [IssuerProtectedHeader](#IssuerProtectedHeader) + + +## Jpt +A JSON Proof Token (JPT). + +**Kind**: global class + +* [Jpt](#Jpt) + * [new Jpt(jpt_string)](#new_Jpt_new) + * [.toString()](#Jpt+toString) ⇒ string + * [.clone()](#Jpt+clone) ⇒ [Jpt](#Jpt) + + + +### new Jpt(jpt_string) +Creates a new [Jpt](#Jpt). + + +| Param | Type | +| --- | --- | +| jpt_string | string | + + + +### jpt.toString() ⇒ string +**Kind**: instance method of [Jpt](#Jpt) + + +### jpt.clone() ⇒ [Jpt](#Jpt) +Deep clones the object. + +**Kind**: instance method of [Jpt](#Jpt) + + +## JptCredentialValidationOptions +Options to declare validation criteria for [Jpt](#Jpt). + +**Kind**: global class + +* [JptCredentialValidationOptions](#JptCredentialValidationOptions) + * [new JptCredentialValidationOptions([opts])](#new_JptCredentialValidationOptions_new) + * _instance_ + * [.clone()](#JptCredentialValidationOptions+clone) ⇒ [JptCredentialValidationOptions](#JptCredentialValidationOptions) + * [.toJSON()](#JptCredentialValidationOptions+toJSON) ⇒ any + * _static_ + * [.fromJSON(json)](#JptCredentialValidationOptions.fromJSON) ⇒ [JptCredentialValidationOptions](#JptCredentialValidationOptions) + + + +### new JptCredentialValidationOptions([opts]) +Creates a new default istance. + + +| Param | Type | +| --- | --- | +| [opts] | IJptCredentialValidationOptions \| undefined | + + + +### jptCredentialValidationOptions.clone() ⇒ [JptCredentialValidationOptions](#JptCredentialValidationOptions) +Deep clones the object. + +**Kind**: instance method of [JptCredentialValidationOptions](#JptCredentialValidationOptions) + + +### jptCredentialValidationOptions.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [JptCredentialValidationOptions](#JptCredentialValidationOptions) + + +### JptCredentialValidationOptions.fromJSON(json) ⇒ [JptCredentialValidationOptions](#JptCredentialValidationOptions) +Deserializes an instance from a JSON object. + +**Kind**: static method of [JptCredentialValidationOptions](#JptCredentialValidationOptions) + +| Param | Type | +| --- | --- | +| json | any | + + + +## JptCredentialValidator +**Kind**: global class + + +### JptCredentialValidator.validate(credential_jpt, issuer, options, fail_fast) ⇒ [DecodedJptCredential](#DecodedJptCredential) +**Kind**: static method of [JptCredentialValidator](#JptCredentialValidator) + +| Param | Type | +| --- | --- | +| credential_jpt | [Jpt](#Jpt) | +| issuer | [CoreDocument](#CoreDocument) \| IToCoreDocument | +| options | [JptCredentialValidationOptions](#JptCredentialValidationOptions) | +| fail_fast | [FailFast](#FailFast) | + + + +## JptCredentialValidatorUtils +Utility functions for validating JPT credentials. + +**Kind**: global class + +* [JptCredentialValidatorUtils](#JptCredentialValidatorUtils) + * [.extractIssuer(credential)](#JptCredentialValidatorUtils.extractIssuer) ⇒ [CoreDID](#CoreDID) + * [.extractIssuerFromIssuedJpt(credential)](#JptCredentialValidatorUtils.extractIssuerFromIssuedJpt) ⇒ [CoreDID](#CoreDID) + * [.checkTimeframesWithValidityTimeframe2024(credential, validity_timeframe, status_check)](#JptCredentialValidatorUtils.checkTimeframesWithValidityTimeframe2024) + * [.checkRevocationWithValidityTimeframe2024(credential, issuer, status_check)](#JptCredentialValidatorUtils.checkRevocationWithValidityTimeframe2024) + * [.checkTimeframesAndRevocationWithValidityTimeframe2024(credential, issuer, validity_timeframe, status_check)](#JptCredentialValidatorUtils.checkTimeframesAndRevocationWithValidityTimeframe2024) + + + +### JptCredentialValidatorUtils.extractIssuer(credential) ⇒ [CoreDID](#CoreDID) +Utility for extracting the issuer field of a [Credential](#Credential) as a DID. +# Errors +Fails if the issuer field is not a valid DID. + +**Kind**: static method of [JptCredentialValidatorUtils](#JptCredentialValidatorUtils) + +| Param | Type | +| --- | --- | +| credential | [Credential](#Credential) | + + + +### JptCredentialValidatorUtils.extractIssuerFromIssuedJpt(credential) ⇒ [CoreDID](#CoreDID) +Utility for extracting the issuer field of a credential in JPT representation as DID. +# Errors +If the JPT decoding fails or the issuer field is not a valid DID. + +**Kind**: static method of [JptCredentialValidatorUtils](#JptCredentialValidatorUtils) + +| Param | Type | +| --- | --- | +| credential | [Jpt](#Jpt) | + + + +### JptCredentialValidatorUtils.checkTimeframesWithValidityTimeframe2024(credential, validity_timeframe, status_check) +**Kind**: static method of [JptCredentialValidatorUtils](#JptCredentialValidatorUtils) + +| Param | Type | +| --- | --- | +| credential | [Credential](#Credential) | +| validity_timeframe | [Timestamp](#Timestamp) \| undefined | +| status_check | [StatusCheck](#StatusCheck) | + + + +### JptCredentialValidatorUtils.checkRevocationWithValidityTimeframe2024(credential, issuer, status_check) +Checks whether the credential status has been revoked. + +Only supports `RevocationTimeframe2024`. + +**Kind**: static method of [JptCredentialValidatorUtils](#JptCredentialValidatorUtils) + +| Param | Type | +| --- | --- | +| credential | [Credential](#Credential) | +| issuer | [CoreDocument](#CoreDocument) \| IToCoreDocument | +| status_check | [StatusCheck](#StatusCheck) | + + + +### JptCredentialValidatorUtils.checkTimeframesAndRevocationWithValidityTimeframe2024(credential, issuer, validity_timeframe, status_check) +Checks whether the credential status has been revoked or the timeframe interval is INVALID + +Only supports `RevocationTimeframe2024`. + +**Kind**: static method of [JptCredentialValidatorUtils](#JptCredentialValidatorUtils) + +| Param | Type | +| --- | --- | +| credential | [Credential](#Credential) | +| issuer | [CoreDocument](#CoreDocument) \| IToCoreDocument | +| validity_timeframe | [Timestamp](#Timestamp) \| undefined | +| status_check | [StatusCheck](#StatusCheck) | + + + +## JptPresentationValidationOptions +Options to declare validation criteria for a [Jpt](#Jpt) presentation. + +**Kind**: global class + +* [JptPresentationValidationOptions](#JptPresentationValidationOptions) + * [new JptPresentationValidationOptions([opts])](#new_JptPresentationValidationOptions_new) + * _instance_ + * [.clone()](#JptPresentationValidationOptions+clone) ⇒ [JptPresentationValidationOptions](#JptPresentationValidationOptions) + * [.toJSON()](#JptPresentationValidationOptions+toJSON) ⇒ any + * _static_ + * [.fromJSON(json)](#JptPresentationValidationOptions.fromJSON) ⇒ [JptPresentationValidationOptions](#JptPresentationValidationOptions) + + + +### new JptPresentationValidationOptions([opts]) + +| Param | Type | +| --- | --- | +| [opts] | IJptPresentationValidationOptions \| undefined | + + + +### jptPresentationValidationOptions.clone() ⇒ [JptPresentationValidationOptions](#JptPresentationValidationOptions) +Deep clones the object. + +**Kind**: instance method of [JptPresentationValidationOptions](#JptPresentationValidationOptions) + + +### jptPresentationValidationOptions.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [JptPresentationValidationOptions](#JptPresentationValidationOptions) + + +### JptPresentationValidationOptions.fromJSON(json) ⇒ [JptPresentationValidationOptions](#JptPresentationValidationOptions) +Deserializes an instance from a JSON object. + +**Kind**: static method of [JptPresentationValidationOptions](#JptPresentationValidationOptions) + +| Param | Type | +| --- | --- | +| json | any | + + + +## JptPresentationValidator +**Kind**: global class + + +### JptPresentationValidator.validate(presentation_jpt, issuer, options, fail_fast) ⇒ [DecodedJptPresentation](#DecodedJptPresentation) +Decodes and validates a Presented [Credential](#Credential) issued as a JPT (JWP Presented Form). A +[DecodedJptPresentation](#DecodedJptPresentation) is returned upon success. + +The following properties are validated according to `options`: +- the holder's proof on the JWP, +- the expiration date, +- the issuance date, +- the semantic structure. + +**Kind**: static method of [JptPresentationValidator](#JptPresentationValidator) + +| Param | Type | +| --- | --- | +| presentation_jpt | [Jpt](#Jpt) | +| issuer | [CoreDocument](#CoreDocument) \| IToCoreDocument | +| options | [JptPresentationValidationOptions](#JptPresentationValidationOptions) | +| fail_fast | [FailFast](#FailFast) | + + + +## JptPresentationValidatorUtils +Utility functions for verifying JPT presentations. + +**Kind**: global class + +* [JptPresentationValidatorUtils](#JptPresentationValidatorUtils) + * [.extractIssuerFromPresentedJpt(presentation)](#JptPresentationValidatorUtils.extractIssuerFromPresentedJpt) ⇒ [CoreDID](#CoreDID) + * [.checkTimeframesWithValidityTimeframe2024(credential, validity_timeframe, status_check)](#JptPresentationValidatorUtils.checkTimeframesWithValidityTimeframe2024) + + + +### JptPresentationValidatorUtils.extractIssuerFromPresentedJpt(presentation) ⇒ [CoreDID](#CoreDID) +Utility for extracting the issuer field of a credential in JPT representation as DID. +# Errors +If the JPT decoding fails or the issuer field is not a valid DID. + +**Kind**: static method of [JptPresentationValidatorUtils](#JptPresentationValidatorUtils) + +| Param | Type | +| --- | --- | +| presentation | [Jpt](#Jpt) | + + + +### JptPresentationValidatorUtils.checkTimeframesWithValidityTimeframe2024(credential, validity_timeframe, status_check) +Check timeframe interval in credentialStatus with `RevocationTimeframeStatus`. + +**Kind**: static method of [JptPresentationValidatorUtils](#JptPresentationValidatorUtils) + +| Param | Type | +| --- | --- | +| credential | [Credential](#Credential) | +| validity_timeframe | [Timestamp](#Timestamp) \| undefined | +| status_check | [StatusCheck](#StatusCheck) | + + + +## Jwk +**Kind**: global class + +* [Jwk](#Jwk) + * [new Jwk(jwk)](#new_Jwk_new) + * _instance_ + * [.kty()](#Jwk+kty) ⇒ JwkType + * [.use()](#Jwk+use) ⇒ JwkUse \| undefined + * [.keyOps()](#Jwk+keyOps) ⇒ Array.<JwkOperation> + * [.alg()](#Jwk+alg) ⇒ JwsAlgorithm \| undefined + * [.kid()](#Jwk+kid) ⇒ string \| undefined + * [.x5u()](#Jwk+x5u) ⇒ string \| undefined + * [.x5c()](#Jwk+x5c) ⇒ Array.<string> + * [.x5t()](#Jwk+x5t) ⇒ string \| undefined + * [.x5t256()](#Jwk+x5t256) ⇒ string \| undefined + * [.paramsEc()](#Jwk+paramsEc) ⇒ JwkParamsEc \| undefined + * [.paramsOkp()](#Jwk+paramsOkp) ⇒ JwkParamsOkp \| undefined + * [.paramsOct()](#Jwk+paramsOct) ⇒ JwkParamsOct \| undefined + * [.paramsRsa()](#Jwk+paramsRsa) ⇒ JwkParamsRsa \| undefined + * [.toPublic()](#Jwk+toPublic) ⇒ [Jwk](#Jwk) \| undefined + * [.isPublic()](#Jwk+isPublic) ⇒ boolean + * [.isPrivate()](#Jwk+isPrivate) ⇒ boolean + * [.toJSON()](#Jwk+toJSON) ⇒ any + * [.clone()](#Jwk+clone) ⇒ [Jwk](#Jwk) + * _static_ + * [.fromJSON(json)](#Jwk.fromJSON) ⇒ [Jwk](#Jwk) + + + +### new Jwk(jwk) + +| Param | Type | +| --- | --- | +| jwk | IJwkParams | + + + +### jwk.kty() ⇒ JwkType +Returns the value for the key type parameter (kty). + +**Kind**: instance method of [Jwk](#Jwk) + + +### jwk.use() ⇒ JwkUse \| undefined +Returns the value for the use property (use). + +**Kind**: instance method of [Jwk](#Jwk) + + +### jwk.keyOps() ⇒ Array.<JwkOperation> +**Kind**: instance method of [Jwk](#Jwk) + + +### jwk.alg() ⇒ JwsAlgorithm \| undefined +Returns the value for the algorithm property (alg). + +**Kind**: instance method of [Jwk](#Jwk) + + +### jwk.kid() ⇒ string \| undefined +Returns the value of the key ID property (kid). + +**Kind**: instance method of [Jwk](#Jwk) + + +### jwk.x5u() ⇒ string \| undefined +Returns the value of the X.509 URL property (x5u). + +**Kind**: instance method of [Jwk](#Jwk) + + +### jwk.x5c() ⇒ Array.<string> +Returns the value of the X.509 certificate chain property (x5c). + +**Kind**: instance method of [Jwk](#Jwk) + + +### jwk.x5t() ⇒ string \| undefined +Returns the value of the X.509 certificate SHA-1 thumbprint property (x5t). + +**Kind**: instance method of [Jwk](#Jwk) + + +### jwk.x5t256() ⇒ string \| undefined +Returns the value of the X.509 certificate SHA-256 thumbprint property (x5t#S256). + +**Kind**: instance method of [Jwk](#Jwk) + + +### jwk.paramsEc() ⇒ JwkParamsEc \| undefined +If this JWK is of kty EC, returns those parameters. + +**Kind**: instance method of [Jwk](#Jwk) + + +### jwk.paramsOkp() ⇒ JwkParamsOkp \| undefined +If this JWK is of kty OKP, returns those parameters. + +**Kind**: instance method of [Jwk](#Jwk) + + +### jwk.paramsOct() ⇒ JwkParamsOct \| undefined +If this JWK is of kty OCT, returns those parameters. + +**Kind**: instance method of [Jwk](#Jwk) + + +### jwk.paramsRsa() ⇒ JwkParamsRsa \| undefined +If this JWK is of kty RSA, returns those parameters. + +**Kind**: instance method of [Jwk](#Jwk) + + +### jwk.toPublic() ⇒ [Jwk](#Jwk) \| undefined +Returns a clone of the [Jwk](#Jwk) with _all_ private key components unset. +Nothing is returned when `kty = oct` as this key type is not considered public by this library. + +**Kind**: instance method of [Jwk](#Jwk) + + +### jwk.isPublic() ⇒ boolean +Returns `true` if _all_ private key components of the key are unset, `false` otherwise. + +**Kind**: instance method of [Jwk](#Jwk) + + +### jwk.isPrivate() ⇒ boolean +Returns `true` if _all_ private key components of the key are set, `false` otherwise. + +**Kind**: instance method of [Jwk](#Jwk) + + +### jwk.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [Jwk](#Jwk) + + +### jwk.clone() ⇒ [Jwk](#Jwk) +Deep clones the object. + +**Kind**: instance method of [Jwk](#Jwk) + + +### Jwk.fromJSON(json) ⇒ [Jwk](#Jwk) +Deserializes an instance from a JSON object. + +**Kind**: static method of [Jwk](#Jwk) + +| Param | Type | +| --- | --- | +| json | any | + + + +## JwkGenOutput +The result of a key generation in `JwkStorage`. + +**Kind**: global class + +* [JwkGenOutput](#JwkGenOutput) + * [new JwkGenOutput(key_id, jwk)](#new_JwkGenOutput_new) + * _instance_ + * [.jwk()](#JwkGenOutput+jwk) ⇒ [Jwk](#Jwk) + * [.keyId()](#JwkGenOutput+keyId) ⇒ string + * [.toJSON()](#JwkGenOutput+toJSON) ⇒ any + * [.clone()](#JwkGenOutput+clone) ⇒ [JwkGenOutput](#JwkGenOutput) + * _static_ + * [.fromJSON(json)](#JwkGenOutput.fromJSON) ⇒ [JwkGenOutput](#JwkGenOutput) + + + +### new JwkGenOutput(key_id, jwk) + +| Param | Type | +| --- | --- | +| key_id | string | +| jwk | [Jwk](#Jwk) | + + + +### jwkGenOutput.jwk() ⇒ [Jwk](#Jwk) +Returns the generated public [Jwk](#Jwk). + +**Kind**: instance method of [JwkGenOutput](#JwkGenOutput) + + +### jwkGenOutput.keyId() ⇒ string +Returns the key id of the generated [Jwk](#Jwk). + +**Kind**: instance method of [JwkGenOutput](#JwkGenOutput) + + +### jwkGenOutput.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [JwkGenOutput](#JwkGenOutput) + + +### jwkGenOutput.clone() ⇒ [JwkGenOutput](#JwkGenOutput) +Deep clones the object. + +**Kind**: instance method of [JwkGenOutput](#JwkGenOutput) + + +### JwkGenOutput.fromJSON(json) ⇒ [JwkGenOutput](#JwkGenOutput) +Deserializes an instance from a JSON object. + +**Kind**: static method of [JwkGenOutput](#JwkGenOutput) + +| Param | Type | +| --- | --- | +| json | any | + + + +## JwpCredentialOptions +**Kind**: global class + +* [JwpCredentialOptions](#JwpCredentialOptions) + * _instance_ + * [.kid](#JwpCredentialOptions+kid) ⇒ string \| undefined + * [.kid](#JwpCredentialOptions+kid) + * [.toJSON()](#JwpCredentialOptions+toJSON) ⇒ any + * _static_ + * [.fromJSON(value)](#JwpCredentialOptions.fromJSON) ⇒ [JwpCredentialOptions](#JwpCredentialOptions) + + + +### jwpCredentialOptions.kid ⇒ string \| undefined +**Kind**: instance property of [JwpCredentialOptions](#JwpCredentialOptions) + + +### jwpCredentialOptions.kid +**Kind**: instance property of [JwpCredentialOptions](#JwpCredentialOptions) + +| Param | Type | +| --- | --- | +| [arg0] | string \| undefined | + + + +### jwpCredentialOptions.toJSON() ⇒ any +**Kind**: instance method of [JwpCredentialOptions](#JwpCredentialOptions) + + +### JwpCredentialOptions.fromJSON(value) ⇒ [JwpCredentialOptions](#JwpCredentialOptions) +**Kind**: static method of [JwpCredentialOptions](#JwpCredentialOptions) + +| Param | Type | +| --- | --- | +| value | any | + + + +## JwpIssued +**Kind**: global class + +* [JwpIssued](#JwpIssued) + * _instance_ + * [.toJSON()](#JwpIssued+toJSON) ⇒ any + * [.clone()](#JwpIssued+clone) ⇒ [JwpIssued](#JwpIssued) + * [.encode(serialization)](#JwpIssued+encode) ⇒ string + * [.setProof(proof)](#JwpIssued+setProof) + * [.getProof()](#JwpIssued+getProof) ⇒ Uint8Array + * [.getPayloads()](#JwpIssued+getPayloads) ⇒ [Payloads](#Payloads) + * [.setPayloads(payloads)](#JwpIssued+setPayloads) + * [.getIssuerProtectedHeader()](#JwpIssued+getIssuerProtectedHeader) ⇒ [IssuerProtectedHeader](#IssuerProtectedHeader) + * _static_ + * [.fromJSON(json)](#JwpIssued.fromJSON) ⇒ [JwpIssued](#JwpIssued) + + + +### jwpIssued.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [JwpIssued](#JwpIssued) + + +### jwpIssued.clone() ⇒ [JwpIssued](#JwpIssued) +Deep clones the object. + +**Kind**: instance method of [JwpIssued](#JwpIssued) + + +### jwpIssued.encode(serialization) ⇒ string +**Kind**: instance method of [JwpIssued](#JwpIssued) + +| Param | Type | +| --- | --- | +| serialization | [SerializationType](#SerializationType) | + + + +### jwpIssued.setProof(proof) +**Kind**: instance method of [JwpIssued](#JwpIssued) + +| Param | Type | +| --- | --- | +| proof | Uint8Array | + + + +### jwpIssued.getProof() ⇒ Uint8Array +**Kind**: instance method of [JwpIssued](#JwpIssued) + + +### jwpIssued.getPayloads() ⇒ [Payloads](#Payloads) +**Kind**: instance method of [JwpIssued](#JwpIssued) + + +### jwpIssued.setPayloads(payloads) +**Kind**: instance method of [JwpIssued](#JwpIssued) + +| Param | Type | +| --- | --- | +| payloads | [Payloads](#Payloads) | + + + +### jwpIssued.getIssuerProtectedHeader() ⇒ [IssuerProtectedHeader](#IssuerProtectedHeader) +**Kind**: instance method of [JwpIssued](#JwpIssued) + + +### JwpIssued.fromJSON(json) ⇒ [JwpIssued](#JwpIssued) +Deserializes an instance from a JSON object. + +**Kind**: static method of [JwpIssued](#JwpIssued) + +| Param | Type | +| --- | --- | +| json | any | + + + +## JwpPresentationOptions +Options to be set in the JWT claims of a verifiable presentation. + +**Kind**: global class + +* [JwpPresentationOptions](#JwpPresentationOptions) + * [.audience](#JwpPresentationOptions+audience) ⇒ string \| undefined + * [.audience](#JwpPresentationOptions+audience) + * [.nonce](#JwpPresentationOptions+nonce) ⇒ string \| undefined + * [.nonce](#JwpPresentationOptions+nonce) + + + +### jwpPresentationOptions.audience ⇒ string \| undefined +Sets the audience for presentation (`aud` property in JWP Presentation Header). + +**Kind**: instance property of [JwpPresentationOptions](#JwpPresentationOptions) + + +### jwpPresentationOptions.audience +Sets the audience for presentation (`aud` property in JWP Presentation Header). + +**Kind**: instance property of [JwpPresentationOptions](#JwpPresentationOptions) + +| Param | Type | +| --- | --- | +| [arg0] | string \| undefined | + + + +### jwpPresentationOptions.nonce ⇒ string \| undefined +The nonce to be placed in the Presentation Protected Header. + +**Kind**: instance property of [JwpPresentationOptions](#JwpPresentationOptions) + + +### jwpPresentationOptions.nonce +The nonce to be placed in the Presentation Protected Header. + +**Kind**: instance property of [JwpPresentationOptions](#JwpPresentationOptions) + +| Param | Type | +| --- | --- | +| [arg0] | string \| undefined | + + + +## JwpVerificationOptions +**Kind**: global class + +* [JwpVerificationOptions](#JwpVerificationOptions) + * _instance_ + * [.clone()](#JwpVerificationOptions+clone) ⇒ [JwpVerificationOptions](#JwpVerificationOptions) + * [.toJSON()](#JwpVerificationOptions+toJSON) ⇒ any + * _static_ + * [.fromJSON(json)](#JwpVerificationOptions.fromJSON) ⇒ [JwpVerificationOptions](#JwpVerificationOptions) + * [.new([opts])](#JwpVerificationOptions.new) ⇒ [JwpVerificationOptions](#JwpVerificationOptions) + + + +### jwpVerificationOptions.clone() ⇒ [JwpVerificationOptions](#JwpVerificationOptions) +Deep clones the object. + +**Kind**: instance method of [JwpVerificationOptions](#JwpVerificationOptions) + + +### jwpVerificationOptions.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [JwpVerificationOptions](#JwpVerificationOptions) + + +### JwpVerificationOptions.fromJSON(json) ⇒ [JwpVerificationOptions](#JwpVerificationOptions) +Deserializes an instance from a JSON object. + +**Kind**: static method of [JwpVerificationOptions](#JwpVerificationOptions) + +| Param | Type | +| --- | --- | +| json | any | + + + +### JwpVerificationOptions.new([opts]) ⇒ [JwpVerificationOptions](#JwpVerificationOptions) +**Kind**: static method of [JwpVerificationOptions](#JwpVerificationOptions) + +| Param | Type | +| --- | --- | +| [opts] | IJwpVerificationOptions \| undefined | + + + +## Jws +A wrapper around a JSON Web Signature (JWS). + +**Kind**: global class + +* [Jws](#Jws) + * [new Jws(jws_string)](#new_Jws_new) + * [.toString()](#Jws+toString) ⇒ string + + + +### new Jws(jws_string) +Creates a new [Jws](#Jws) from the given string. + + +| Param | Type | +| --- | --- | +| jws_string | string | + + + +### jws.toString() ⇒ string +Returns a clone of the JWS string. + +**Kind**: instance method of [Jws](#Jws) + + +## JwsHeader +**Kind**: global class + +* [JwsHeader](#JwsHeader) + * [new JwsHeader()](#new_JwsHeader_new) + * _instance_ + * [.alg()](#JwsHeader+alg) ⇒ JwsAlgorithm \| undefined + * [.setAlg(value)](#JwsHeader+setAlg) + * [.b64()](#JwsHeader+b64) ⇒ boolean \| undefined + * [.setB64(value)](#JwsHeader+setB64) + * [.custom()](#JwsHeader+custom) ⇒ Record.<string, any> \| undefined + * [.has(claim)](#JwsHeader+has) ⇒ boolean + * [.isDisjoint(other)](#JwsHeader+isDisjoint) ⇒ boolean + * [.jku()](#JwsHeader+jku) ⇒ string \| undefined + * [.setJku(value)](#JwsHeader+setJku) + * [.jwk()](#JwsHeader+jwk) ⇒ [Jwk](#Jwk) \| undefined + * [.setJwk(value)](#JwsHeader+setJwk) + * [.kid()](#JwsHeader+kid) ⇒ string \| undefined + * [.setKid(value)](#JwsHeader+setKid) + * [.x5u()](#JwsHeader+x5u) ⇒ string \| undefined + * [.setX5u(value)](#JwsHeader+setX5u) + * [.x5c()](#JwsHeader+x5c) ⇒ Array.<string> + * [.setX5c(value)](#JwsHeader+setX5c) + * [.x5t()](#JwsHeader+x5t) ⇒ string \| undefined + * [.setX5t(value)](#JwsHeader+setX5t) + * [.x5tS256()](#JwsHeader+x5tS256) ⇒ string \| undefined + * [.setX5tS256(value)](#JwsHeader+setX5tS256) + * [.typ()](#JwsHeader+typ) ⇒ string \| undefined + * [.setTyp(value)](#JwsHeader+setTyp) + * [.cty()](#JwsHeader+cty) ⇒ string \| undefined + * [.setCty(value)](#JwsHeader+setCty) + * [.crit()](#JwsHeader+crit) ⇒ Array.<string> + * [.setCrit(value)](#JwsHeader+setCrit) + * [.url()](#JwsHeader+url) ⇒ string \| undefined + * [.setUrl(value)](#JwsHeader+setUrl) + * [.nonce()](#JwsHeader+nonce) ⇒ string \| undefined + * [.setNonce(value)](#JwsHeader+setNonce) + * [.toJSON()](#JwsHeader+toJSON) ⇒ any + * [.clone()](#JwsHeader+clone) ⇒ [JwsHeader](#JwsHeader) + * _static_ + * [.fromJSON(json)](#JwsHeader.fromJSON) ⇒ [JwsHeader](#JwsHeader) + + + +### new JwsHeader() +Create a new empty [JwsHeader](#JwsHeader). + + + +### jwsHeader.alg() ⇒ JwsAlgorithm \| undefined +Returns the value for the algorithm claim (alg). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + + +### jwsHeader.setAlg(value) +Sets a value for the algorithm claim (alg). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + +| Param | Type | +| --- | --- | +| value | JwsAlgorithm | + + + +### jwsHeader.b64() ⇒ boolean \| undefined +Returns the value of the base64url-encode payload claim (b64). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + + +### jwsHeader.setB64(value) +Sets a value for the base64url-encode payload claim (b64). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + +| Param | Type | +| --- | --- | +| value | boolean | + + + +### jwsHeader.custom() ⇒ Record.<string, any> \| undefined +Additional header parameters. + +**Kind**: instance method of [JwsHeader](#JwsHeader) + + +### jwsHeader.has(claim) ⇒ boolean +**Kind**: instance method of [JwsHeader](#JwsHeader) + +| Param | Type | +| --- | --- | +| claim | string | + + + +### jwsHeader.isDisjoint(other) ⇒ boolean +Returns `true` if none of the fields are set in both `self` and `other`. + +**Kind**: instance method of [JwsHeader](#JwsHeader) + +| Param | Type | +| --- | --- | +| other | [JwsHeader](#JwsHeader) | + + + +### jwsHeader.jku() ⇒ string \| undefined +Returns the value of the JWK Set URL claim (jku). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + + +### jwsHeader.setJku(value) +Sets a value for the JWK Set URL claim (jku). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + +| Param | Type | +| --- | --- | +| value | string | + + + +### jwsHeader.jwk() ⇒ [Jwk](#Jwk) \| undefined +Returns the value of the JWK claim (jwk). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + + +### jwsHeader.setJwk(value) +Sets a value for the JWK claim (jwk). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + +| Param | Type | +| --- | --- | +| value | [Jwk](#Jwk) | + + + +### jwsHeader.kid() ⇒ string \| undefined +Returns the value of the key ID claim (kid). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + + +### jwsHeader.setKid(value) +Sets a value for the key ID claim (kid). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + +| Param | Type | +| --- | --- | +| value | string | + + + +### jwsHeader.x5u() ⇒ string \| undefined +Returns the value of the X.509 URL claim (x5u). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + + +### jwsHeader.setX5u(value) +Sets a value for the X.509 URL claim (x5u). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + +| Param | Type | +| --- | --- | +| value | string | + + + +### jwsHeader.x5c() ⇒ Array.<string> +Returns the value of the X.509 certificate chain claim (x5c). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + + +### jwsHeader.setX5c(value) +Sets values for the X.509 certificate chain claim (x5c). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + +| Param | Type | +| --- | --- | +| value | Array.<string> | + + + +### jwsHeader.x5t() ⇒ string \| undefined +Returns the value of the X.509 certificate SHA-1 thumbprint claim (x5t). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + + +### jwsHeader.setX5t(value) +Sets a value for the X.509 certificate SHA-1 thumbprint claim (x5t). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + +| Param | Type | +| --- | --- | +| value | string | + + + +### jwsHeader.x5tS256() ⇒ string \| undefined +Returns the value of the X.509 certificate SHA-256 thumbprint claim +(x5t#S256). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + + +### jwsHeader.setX5tS256(value) +Sets a value for the X.509 certificate SHA-256 thumbprint claim +(x5t#S256). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + +| Param | Type | +| --- | --- | +| value | string | + + + +### jwsHeader.typ() ⇒ string \| undefined +Returns the value of the token type claim (typ). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + + +### jwsHeader.setTyp(value) +Sets a value for the token type claim (typ). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + +| Param | Type | +| --- | --- | +| value | string | + + + +### jwsHeader.cty() ⇒ string \| undefined +Returns the value of the content type claim (cty). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + + +### jwsHeader.setCty(value) +Sets a value for the content type claim (cty). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + +| Param | Type | +| --- | --- | +| value | string | + + + +### jwsHeader.crit() ⇒ Array.<string> +Returns the value of the critical claim (crit). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + + +### jwsHeader.setCrit(value) +Sets values for the critical claim (crit). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + +| Param | Type | +| --- | --- | +| value | Array.<string> | + + + +### jwsHeader.url() ⇒ string \| undefined +Returns the value of the url claim (url). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + + +### jwsHeader.setUrl(value) +Sets a value for the url claim (url). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + +| Param | Type | +| --- | --- | +| value | string | + + + +### jwsHeader.nonce() ⇒ string \| undefined +Returns the value of the nonce claim (nonce). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + + +### jwsHeader.setNonce(value) +Sets a value for the nonce claim (nonce). + +**Kind**: instance method of [JwsHeader](#JwsHeader) + +| Param | Type | +| --- | --- | +| value | string | + + + +### jwsHeader.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [JwsHeader](#JwsHeader) + + +### jwsHeader.clone() ⇒ [JwsHeader](#JwsHeader) +Deep clones the object. + +**Kind**: instance method of [JwsHeader](#JwsHeader) + + +### JwsHeader.fromJSON(json) ⇒ [JwsHeader](#JwsHeader) +Deserializes an instance from a JSON object. + +**Kind**: static method of [JwsHeader](#JwsHeader) + +| Param | Type | +| --- | --- | +| json | any | + + + +## JwsSignatureOptions +**Kind**: global class + +* [JwsSignatureOptions](#JwsSignatureOptions) + * [new JwsSignatureOptions([options])](#new_JwsSignatureOptions_new) + * _instance_ + * [.setAttachJwk(value)](#JwsSignatureOptions+setAttachJwk) + * [.setB64(value)](#JwsSignatureOptions+setB64) + * [.setTyp(value)](#JwsSignatureOptions+setTyp) + * [.setCty(value)](#JwsSignatureOptions+setCty) + * [.serUrl(value)](#JwsSignatureOptions+serUrl) + * [.setNonce(value)](#JwsSignatureOptions+setNonce) + * [.setKid(value)](#JwsSignatureOptions+setKid) + * [.setDetachedPayload(value)](#JwsSignatureOptions+setDetachedPayload) + * [.setCustomHeaderParameters(value)](#JwsSignatureOptions+setCustomHeaderParameters) + * [.toJSON()](#JwsSignatureOptions+toJSON) ⇒ any + * [.clone()](#JwsSignatureOptions+clone) ⇒ [JwsSignatureOptions](#JwsSignatureOptions) + * _static_ + * [.fromJSON(json)](#JwsSignatureOptions.fromJSON) ⇒ [JwsSignatureOptions](#JwsSignatureOptions) + + + +### new JwsSignatureOptions([options]) + +| Param | Type | +| --- | --- | +| [options] | IJwsSignatureOptions \| undefined | + + + +### jwsSignatureOptions.setAttachJwk(value) +Replace the value of the `attachJwk` field. + +**Kind**: instance method of [JwsSignatureOptions](#JwsSignatureOptions) + +| Param | Type | +| --- | --- | +| value | boolean | + + + +### jwsSignatureOptions.setB64(value) +Replace the value of the `b64` field. + +**Kind**: instance method of [JwsSignatureOptions](#JwsSignatureOptions) + +| Param | Type | +| --- | --- | +| value | boolean | + + + +### jwsSignatureOptions.setTyp(value) +Replace the value of the `typ` field. + +**Kind**: instance method of [JwsSignatureOptions](#JwsSignatureOptions) + +| Param | Type | +| --- | --- | +| value | string | + + + +### jwsSignatureOptions.setCty(value) +Replace the value of the `cty` field. + +**Kind**: instance method of [JwsSignatureOptions](#JwsSignatureOptions) + +| Param | Type | +| --- | --- | +| value | string | + + + +### jwsSignatureOptions.serUrl(value) +Replace the value of the `url` field. + +**Kind**: instance method of [JwsSignatureOptions](#JwsSignatureOptions) + +| Param | Type | +| --- | --- | +| value | string | + + + +### jwsSignatureOptions.setNonce(value) +Replace the value of the `nonce` field. + +**Kind**: instance method of [JwsSignatureOptions](#JwsSignatureOptions) + +| Param | Type | +| --- | --- | +| value | string | + + + +### jwsSignatureOptions.setKid(value) +Replace the value of the `kid` field. + +**Kind**: instance method of [JwsSignatureOptions](#JwsSignatureOptions) + +| Param | Type | +| --- | --- | +| value | string | + + + +### jwsSignatureOptions.setDetachedPayload(value) +Replace the value of the `detached_payload` field. + +**Kind**: instance method of [JwsSignatureOptions](#JwsSignatureOptions) + +| Param | Type | +| --- | --- | +| value | boolean | + + + +### jwsSignatureOptions.setCustomHeaderParameters(value) +Add additional header parameters. + +**Kind**: instance method of [JwsSignatureOptions](#JwsSignatureOptions) + +| Param | Type | +| --- | --- | +| value | Record.<string, any> | + + + +### jwsSignatureOptions.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [JwsSignatureOptions](#JwsSignatureOptions) + + +### jwsSignatureOptions.clone() ⇒ [JwsSignatureOptions](#JwsSignatureOptions) +Deep clones the object. + +**Kind**: instance method of [JwsSignatureOptions](#JwsSignatureOptions) + + +### JwsSignatureOptions.fromJSON(json) ⇒ [JwsSignatureOptions](#JwsSignatureOptions) +Deserializes an instance from a JSON object. + +**Kind**: static method of [JwsSignatureOptions](#JwsSignatureOptions) + +| Param | Type | +| --- | --- | +| json | any | + + + +## JwsVerificationOptions +**Kind**: global class + +* [JwsVerificationOptions](#JwsVerificationOptions) + * [new JwsVerificationOptions([options])](#new_JwsVerificationOptions_new) + * _instance_ + * [.setNonce(value)](#JwsVerificationOptions+setNonce) + * [.setMethodScope(value)](#JwsVerificationOptions+setMethodScope) + * [.setMethodId(value)](#JwsVerificationOptions+setMethodId) + * [.toJSON()](#JwsVerificationOptions+toJSON) ⇒ any + * [.clone()](#JwsVerificationOptions+clone) ⇒ [JwsVerificationOptions](#JwsVerificationOptions) + * _static_ + * [.fromJSON(json)](#JwsVerificationOptions.fromJSON) ⇒ [JwsVerificationOptions](#JwsVerificationOptions) + + + +### new JwsVerificationOptions([options]) +Creates a new [JwsVerificationOptions](#JwsVerificationOptions) from the given fields. + + +| Param | Type | +| --- | --- | +| [options] | IJwsVerificationOptions \| undefined | + + + +### jwsVerificationOptions.setNonce(value) +Set the expected value for the `nonce` parameter of the protected header. + +**Kind**: instance method of [JwsVerificationOptions](#JwsVerificationOptions) + +| Param | Type | +| --- | --- | +| value | string | + + + +### jwsVerificationOptions.setMethodScope(value) +Set the scope of the verification methods that may be used to verify the given JWS. + +**Kind**: instance method of [JwsVerificationOptions](#JwsVerificationOptions) + +| Param | Type | +| --- | --- | +| value | [MethodScope](#MethodScope) | + + + +### jwsVerificationOptions.setMethodId(value) +Set the DID URl of the method, whose JWK should be used to verify the JWS. + +**Kind**: instance method of [JwsVerificationOptions](#JwsVerificationOptions) + +| Param | Type | +| --- | --- | +| value | [DIDUrl](#DIDUrl) | + + + +### jwsVerificationOptions.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [JwsVerificationOptions](#JwsVerificationOptions) + + +### jwsVerificationOptions.clone() ⇒ [JwsVerificationOptions](#JwsVerificationOptions) +Deep clones the object. + +**Kind**: instance method of [JwsVerificationOptions](#JwsVerificationOptions) + + +### JwsVerificationOptions.fromJSON(json) ⇒ [JwsVerificationOptions](#JwsVerificationOptions) +Deserializes an instance from a JSON object. + +**Kind**: static method of [JwsVerificationOptions](#JwsVerificationOptions) + +| Param | Type | +| --- | --- | +| json | any | + + + +## Jwt +A wrapper around a JSON Web Token (JWK). + +**Kind**: global class + +* [Jwt](#Jwt) + * [new Jwt(jwt_string)](#new_Jwt_new) + * _instance_ + * [.toString()](#Jwt+toString) ⇒ string + * [.toJSON()](#Jwt+toJSON) ⇒ any + * [.clone()](#Jwt+clone) ⇒ [Jwt](#Jwt) + * _static_ + * [.fromJSON(json)](#Jwt.fromJSON) ⇒ [Jwt](#Jwt) + + + +### new Jwt(jwt_string) +Creates a new [Jwt](#Jwt) from the given string. + + +| Param | Type | +| --- | --- | +| jwt_string | string | + + + +### jwt.toString() ⇒ string +Returns a clone of the JWT string. + +**Kind**: instance method of [Jwt](#Jwt) + + +### jwt.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [Jwt](#Jwt) + + +### jwt.clone() ⇒ [Jwt](#Jwt) +Deep clones the object. + +**Kind**: instance method of [Jwt](#Jwt) + + +### Jwt.fromJSON(json) ⇒ [Jwt](#Jwt) +Deserializes an instance from a JSON object. + +**Kind**: static method of [Jwt](#Jwt) + +| Param | Type | +| --- | --- | +| json | any | + + + +## JwtCredentialValidationOptions +Options to declare validation criteria when validating credentials. + +**Kind**: global class + +* [JwtCredentialValidationOptions](#JwtCredentialValidationOptions) + * [new JwtCredentialValidationOptions([options])](#new_JwtCredentialValidationOptions_new) + * _instance_ + * [.toJSON()](#JwtCredentialValidationOptions+toJSON) ⇒ any + * [.clone()](#JwtCredentialValidationOptions+clone) ⇒ [JwtCredentialValidationOptions](#JwtCredentialValidationOptions) + * _static_ + * [.fromJSON(json)](#JwtCredentialValidationOptions.fromJSON) ⇒ [JwtCredentialValidationOptions](#JwtCredentialValidationOptions) + + + +### new JwtCredentialValidationOptions([options]) + +| Param | Type | +| --- | --- | +| [options] | IJwtCredentialValidationOptions \| undefined | + + + +### jwtCredentialValidationOptions.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [JwtCredentialValidationOptions](#JwtCredentialValidationOptions) + + +### jwtCredentialValidationOptions.clone() ⇒ [JwtCredentialValidationOptions](#JwtCredentialValidationOptions) +Deep clones the object. + +**Kind**: instance method of [JwtCredentialValidationOptions](#JwtCredentialValidationOptions) + + +### JwtCredentialValidationOptions.fromJSON(json) ⇒ [JwtCredentialValidationOptions](#JwtCredentialValidationOptions) +Deserializes an instance from a JSON object. + +**Kind**: static method of [JwtCredentialValidationOptions](#JwtCredentialValidationOptions) + +| Param | Type | +| --- | --- | +| json | any | + + + +## JwtCredentialValidator +A type for decoding and validating [Credential](#Credential). + +**Kind**: global class + +* [JwtCredentialValidator](#JwtCredentialValidator) + * [new JwtCredentialValidator(signatureVerifier)](#new_JwtCredentialValidator_new) + * _instance_ + * [.validate(credential_jwt, issuer, options, fail_fast)](#JwtCredentialValidator+validate) ⇒ [DecodedJwtCredential](#DecodedJwtCredential) + * [.verifySignature(credential, trustedIssuers, options)](#JwtCredentialValidator+verifySignature) ⇒ [DecodedJwtCredential](#DecodedJwtCredential) + * _static_ + * [.checkExpiresOnOrAfter(credential, timestamp)](#JwtCredentialValidator.checkExpiresOnOrAfter) + * [.checkIssuedOnOrBefore(credential, timestamp)](#JwtCredentialValidator.checkIssuedOnOrBefore) + * [.checkSubjectHolderRelationship(credential, holder, relationship)](#JwtCredentialValidator.checkSubjectHolderRelationship) + * [.checkStatus(credential, trustedIssuers, statusCheck)](#JwtCredentialValidator.checkStatus) + * [.checkStatusWithStatusList2021(credential, status_list, status_check)](#JwtCredentialValidator.checkStatusWithStatusList2021) + * [.extractIssuer(credential)](#JwtCredentialValidator.extractIssuer) ⇒ [CoreDID](#CoreDID) + * [.extractIssuerFromJwt(credential)](#JwtCredentialValidator.extractIssuerFromJwt) ⇒ [CoreDID](#CoreDID) + + + +### new JwtCredentialValidator(signatureVerifier) +Creates a new [JwtCredentialValidator](#JwtCredentialValidator). If a `signatureVerifier` is provided it will be used when +verifying decoded JWS signatures, otherwise the default which is only capable of handling the `EdDSA` +algorithm will be used. + + +| Param | Type | +| --- | --- | +| signatureVerifier | IJwsVerifier | + + + +### jwtCredentialValidator.validate(credential_jwt, issuer, options, fail_fast) ⇒ [DecodedJwtCredential](#DecodedJwtCredential) +Decodes and validates a [Credential](#Credential) issued as a JWS. A [DecodedJwtCredential](#DecodedJwtCredential) is returned upon +success. + +The following properties are validated according to `options`: +- the issuer's signature on the JWS, +- the expiration date, +- the issuance date, +- the semantic structure. + +# Warning +The lack of an error returned from this method is in of itself not enough to conclude that the credential can be +trusted. This section contains more information on additional checks that should be carried out before and after +calling this method. + +## The state of the issuer's DID Document +The caller must ensure that `issuer` represents an up-to-date DID Document. + +## Properties that are not validated + There are many properties defined in [The Verifiable Credentials Data Model](https://www.w3.org/TR/vc-data-model/) that are **not** validated, such as: +`proof`, `credentialStatus`, `type`, `credentialSchema`, `refreshService` **and more**. +These should be manually checked after validation, according to your requirements. + +# Errors +An error is returned whenever a validated condition is not satisfied. + +**Kind**: instance method of [JwtCredentialValidator](#JwtCredentialValidator) + +| Param | Type | +| --- | --- | +| credential_jwt | [Jwt](#Jwt) | +| issuer | [CoreDocument](#CoreDocument) \| IToCoreDocument | +| options | [JwtCredentialValidationOptions](#JwtCredentialValidationOptions) | +| fail_fast | [FailFast](#FailFast) | + + + +### jwtCredentialValidator.verifySignature(credential, trustedIssuers, options) ⇒ [DecodedJwtCredential](#DecodedJwtCredential) +Decode and verify the JWS signature of a [Credential](#Credential) issued as a JWT using the DID Document of a trusted +issuer. + +A [DecodedJwtCredential](#DecodedJwtCredential) is returned upon success. + +# Warning +The caller must ensure that the DID Documents of the trusted issuers are up-to-date. + +## Proofs + Only the JWS signature is verified. If the [Credential](#Credential) contains a `proof` property this will not be +verified by this method. + +# Errors +This method immediately returns an error if +the credential issuer' url cannot be parsed to a DID belonging to one of the trusted issuers. Otherwise an attempt +to verify the credential's signature will be made and an error is returned upon failure. + +**Kind**: instance method of [JwtCredentialValidator](#JwtCredentialValidator) + +| Param | Type | +| --- | --- | +| credential | [Jwt](#Jwt) | +| trustedIssuers | Array.<(CoreDocument\|IToCoreDocument)> | +| options | [JwsVerificationOptions](#JwsVerificationOptions) | + + + +### JwtCredentialValidator.checkExpiresOnOrAfter(credential, timestamp) +Validate that the credential expires on or after the specified timestamp. + +**Kind**: static method of [JwtCredentialValidator](#JwtCredentialValidator) + +| Param | Type | +| --- | --- | +| credential | [Credential](#Credential) | +| timestamp | [Timestamp](#Timestamp) | + + + +### JwtCredentialValidator.checkIssuedOnOrBefore(credential, timestamp) +Validate that the credential is issued on or before the specified timestamp. + +**Kind**: static method of [JwtCredentialValidator](#JwtCredentialValidator) + +| Param | Type | +| --- | --- | +| credential | [Credential](#Credential) | +| timestamp | [Timestamp](#Timestamp) | + + + +### JwtCredentialValidator.checkSubjectHolderRelationship(credential, holder, relationship) +Validate that the relationship between the `holder` and the credential subjects is in accordance with +`relationship`. The `holder` parameter is expected to be the URL of the holder. + +**Kind**: static method of [JwtCredentialValidator](#JwtCredentialValidator) + +| Param | Type | +| --- | --- | +| credential | [Credential](#Credential) | +| holder | string | +| relationship | [SubjectHolderRelationship](#SubjectHolderRelationship) | + + + +### JwtCredentialValidator.checkStatus(credential, trustedIssuers, statusCheck) +Checks whether the credential status has been revoked. + +Only supports `RevocationBitmap2022`. + +**Kind**: static method of [JwtCredentialValidator](#JwtCredentialValidator) + +| Param | Type | +| --- | --- | +| credential | [Credential](#Credential) | +| trustedIssuers | Array.<(CoreDocument\|IToCoreDocument)> | +| statusCheck | [StatusCheck](#StatusCheck) | + + + +### JwtCredentialValidator.checkStatusWithStatusList2021(credential, status_list, status_check) +Checks wheter the credential status has been revoked using `StatusList2021`. + +**Kind**: static method of [JwtCredentialValidator](#JwtCredentialValidator) + +| Param | Type | +| --- | --- | +| credential | [Credential](#Credential) | +| status_list | [StatusList2021Credential](#StatusList2021Credential) | +| status_check | [StatusCheck](#StatusCheck) | + + + +### JwtCredentialValidator.extractIssuer(credential) ⇒ [CoreDID](#CoreDID) +Utility for extracting the issuer field of a [Credential](#Credential) as a DID. + +### Errors + +Fails if the issuer field is not a valid DID. + +**Kind**: static method of [JwtCredentialValidator](#JwtCredentialValidator) + +| Param | Type | +| --- | --- | +| credential | [Credential](#Credential) | + + + +### JwtCredentialValidator.extractIssuerFromJwt(credential) ⇒ [CoreDID](#CoreDID) +Utility for extracting the issuer field of a credential in JWT representation as DID. + +# Errors + +If the JWT decoding fails or the issuer field is not a valid DID. + +**Kind**: static method of [JwtCredentialValidator](#JwtCredentialValidator) + +| Param | Type | +| --- | --- | +| credential | [Jwt](#Jwt) | + + + +## JwtDomainLinkageValidator +A validator for a Domain Linkage Configuration and Credentials. + +**Kind**: global class + +* [JwtDomainLinkageValidator](#JwtDomainLinkageValidator) + * [new JwtDomainLinkageValidator(signatureVerifier)](#new_JwtDomainLinkageValidator_new) + * [.validateLinkage(issuer, configuration, domain, options)](#JwtDomainLinkageValidator+validateLinkage) + * [.validateCredential(issuer, credentialJwt, domain, options)](#JwtDomainLinkageValidator+validateCredential) + + + +### new JwtDomainLinkageValidator(signatureVerifier) +Creates a new [JwtDomainLinkageValidator](#JwtDomainLinkageValidator). If a `signatureVerifier` is provided it will be used when +verifying decoded JWS signatures, otherwise the default which is only capable of handling the `EdDSA` +algorithm will be used. + + +| Param | Type | +| --- | --- | +| signatureVerifier | IJwsVerifier | + + + +### jwtDomainLinkageValidator.validateLinkage(issuer, configuration, domain, options) +Validates the linkage between a domain and a DID. +[DomainLinkageConfiguration](#DomainLinkageConfiguration) is validated according to [DID Configuration Resource Verification](https://identity.foundation/.well-known/resources/did-configuration/#did-configuration-resource-verification). + +Linkage is valid if no error is thrown. + +# Note: +- Only the [JSON Web Token Proof Format](https://identity.foundation/.well-known/resources/did-configuration/#json-web-token-proof-format) + is supported. +- Only the Credential issued by `issuer` is verified. + +# Errors + + - Semantic structure of `configuration` is invalid. + - `configuration` includes multiple credentials issued by `issuer`. + - Validation of the matched Domain Linkage Credential fails. + +**Kind**: instance method of [JwtDomainLinkageValidator](#JwtDomainLinkageValidator) + +| Param | Type | +| --- | --- | +| issuer | [CoreDocument](#CoreDocument) \| IToCoreDocument | +| configuration | [DomainLinkageConfiguration](#DomainLinkageConfiguration) | +| domain | string | +| options | [JwtCredentialValidationOptions](#JwtCredentialValidationOptions) | + + + +### jwtDomainLinkageValidator.validateCredential(issuer, credentialJwt, domain, options) +Validates a [Domain Linkage Credential](https://identity.foundation/.well-known/resources/did-configuration/#domain-linkage-credential). + +Error will be thrown in case the validation fails. + +**Kind**: instance method of [JwtDomainLinkageValidator](#JwtDomainLinkageValidator) + +| Param | Type | +| --- | --- | +| issuer | [CoreDocument](#CoreDocument) \| IToCoreDocument | +| credentialJwt | [Jwt](#Jwt) | +| domain | string | +| options | [JwtCredentialValidationOptions](#JwtCredentialValidationOptions) | + + + +## JwtPresentationOptions +**Kind**: global class + +* [JwtPresentationOptions](#JwtPresentationOptions) + * [new JwtPresentationOptions([options])](#new_JwtPresentationOptions_new) + * _instance_ + * [.toJSON()](#JwtPresentationOptions+toJSON) ⇒ any + * [.clone()](#JwtPresentationOptions+clone) ⇒ [JwtPresentationOptions](#JwtPresentationOptions) + * _static_ + * [.fromJSON(json)](#JwtPresentationOptions.fromJSON) ⇒ [JwtPresentationOptions](#JwtPresentationOptions) + + + +### new JwtPresentationOptions([options]) +Creates a new [JwtPresentationOptions](#JwtPresentationOptions) from the given fields. + +Throws an error if any of the options are invalid. + + +| Param | Type | +| --- | --- | +| [options] | IJwtPresentationOptions \| undefined | + + + +### jwtPresentationOptions.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [JwtPresentationOptions](#JwtPresentationOptions) + + +### jwtPresentationOptions.clone() ⇒ [JwtPresentationOptions](#JwtPresentationOptions) +Deep clones the object. + +**Kind**: instance method of [JwtPresentationOptions](#JwtPresentationOptions) + + +### JwtPresentationOptions.fromJSON(json) ⇒ [JwtPresentationOptions](#JwtPresentationOptions) +Deserializes an instance from a JSON object. + +**Kind**: static method of [JwtPresentationOptions](#JwtPresentationOptions) + +| Param | Type | +| --- | --- | +| json | any | + + + +## JwtPresentationValidationOptions +Options to declare validation criteria when validating presentation. + +**Kind**: global class + +* [JwtPresentationValidationOptions](#JwtPresentationValidationOptions) + * [new JwtPresentationValidationOptions([options])](#new_JwtPresentationValidationOptions_new) + * _instance_ + * [.toJSON()](#JwtPresentationValidationOptions+toJSON) ⇒ any + * [.clone()](#JwtPresentationValidationOptions+clone) ⇒ [JwtPresentationValidationOptions](#JwtPresentationValidationOptions) + * _static_ + * [.fromJSON(json)](#JwtPresentationValidationOptions.fromJSON) ⇒ [JwtPresentationValidationOptions](#JwtPresentationValidationOptions) + + + +### new JwtPresentationValidationOptions([options]) +Creates a new [JwtPresentationValidationOptions](#JwtPresentationValidationOptions) from the given fields. + +Throws an error if any of the options are invalid. + + +| Param | Type | +| --- | --- | +| [options] | IJwtPresentationValidationOptions \| undefined | + + + +### jwtPresentationValidationOptions.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [JwtPresentationValidationOptions](#JwtPresentationValidationOptions) + + +### jwtPresentationValidationOptions.clone() ⇒ [JwtPresentationValidationOptions](#JwtPresentationValidationOptions) +Deep clones the object. + +**Kind**: instance method of [JwtPresentationValidationOptions](#JwtPresentationValidationOptions) + + +### JwtPresentationValidationOptions.fromJSON(json) ⇒ [JwtPresentationValidationOptions](#JwtPresentationValidationOptions) +Deserializes an instance from a JSON object. + +**Kind**: static method of [JwtPresentationValidationOptions](#JwtPresentationValidationOptions) + +| Param | Type | +| --- | --- | +| json | any | + + + +## JwtPresentationValidator +**Kind**: global class + +* [JwtPresentationValidator](#JwtPresentationValidator) + * [new JwtPresentationValidator(signatureVerifier)](#new_JwtPresentationValidator_new) + * _instance_ + * [.validate(presentationJwt, holder, validation_options)](#JwtPresentationValidator+validate) ⇒ [DecodedJwtPresentation](#DecodedJwtPresentation) + * _static_ + * [.checkStructure(presentation)](#JwtPresentationValidator.checkStructure) + * [.extractHolder(presentation)](#JwtPresentationValidator.extractHolder) ⇒ [CoreDID](#CoreDID) + + + +### new JwtPresentationValidator(signatureVerifier) +Creates a new [JwtPresentationValidator](#JwtPresentationValidator). If a `signatureVerifier` is provided it will be used when +verifying decoded JWS signatures, otherwise the default which is only capable of handling the `EdDSA` +algorithm will be used. + + +| Param | Type | +| --- | --- | +| signatureVerifier | IJwsVerifier | + + + +### jwtPresentationValidator.validate(presentationJwt, holder, validation_options) ⇒ [DecodedJwtPresentation](#DecodedJwtPresentation) +Validates a [Presentation](#Presentation) encoded as a [Jwt](#Jwt). + +The following properties are validated according to `options`: +- the JWT can be decoded into a semantically valid presentation. +- the expiration and issuance date contained in the JWT claims. +- the holder's signature. + +Validation is done with respect to the properties set in `options`. + +# Warning + +* This method does NOT validate the constituent credentials and therefore also not the relationship between the +credentials' subjects and the presentation holder. This can be done with [JwtCredentialValidationOptions](#JwtCredentialValidationOptions). +* The lack of an error returned from this method is in of itself not enough to conclude that the presentation can +be trusted. This section contains more information on additional checks that should be carried out before and +after calling this method. + +## The state of the supplied DID Documents. + +The caller must ensure that the DID Documents in `holder` are up-to-date. + +# Errors + +An error is returned whenever a validated condition is not satisfied or when decoding fails. + +**Kind**: instance method of [JwtPresentationValidator](#JwtPresentationValidator) + +| Param | Type | +| --- | --- | +| presentationJwt | [Jwt](#Jwt) | +| holder | [CoreDocument](#CoreDocument) \| IToCoreDocument | +| validation_options | [JwtPresentationValidationOptions](#JwtPresentationValidationOptions) | + + + +### JwtPresentationValidator.checkStructure(presentation) +Validates the semantic structure of the [Presentation](#Presentation). + +**Kind**: static method of [JwtPresentationValidator](#JwtPresentationValidator) + +| Param | Type | +| --- | --- | +| presentation | [Presentation](#Presentation) | + + + +### JwtPresentationValidator.extractHolder(presentation) ⇒ [CoreDID](#CoreDID) +Attempt to extract the holder of the presentation. + +# Errors: +* If deserialization/decoding of the presentation fails. +* If the holder can't be parsed as DIDs. + +**Kind**: static method of [JwtPresentationValidator](#JwtPresentationValidator) + +| Param | Type | +| --- | --- | +| presentation | [Jwt](#Jwt) | + + + +## KeyBindingJWTValidationOptions +Options to declare validation criteria when validating credentials. + +**Kind**: global class + +* [KeyBindingJWTValidationOptions](#KeyBindingJWTValidationOptions) + * [new KeyBindingJWTValidationOptions([options])](#new_KeyBindingJWTValidationOptions_new) + * _instance_ + * [.toJSON()](#KeyBindingJWTValidationOptions+toJSON) ⇒ any + * [.clone()](#KeyBindingJWTValidationOptions+clone) ⇒ [KeyBindingJWTValidationOptions](#KeyBindingJWTValidationOptions) + * _static_ + * [.fromJSON(json)](#KeyBindingJWTValidationOptions.fromJSON) ⇒ [KeyBindingJWTValidationOptions](#KeyBindingJWTValidationOptions) + + + +### new KeyBindingJWTValidationOptions([options]) + +| Param | Type | +| --- | --- | +| [options] | IKeyBindingJWTValidationOptions \| undefined | + + + +### keyBindingJWTValidationOptions.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [KeyBindingJWTValidationOptions](#KeyBindingJWTValidationOptions) + + +### keyBindingJWTValidationOptions.clone() ⇒ [KeyBindingJWTValidationOptions](#KeyBindingJWTValidationOptions) +Deep clones the object. + +**Kind**: instance method of [KeyBindingJWTValidationOptions](#KeyBindingJWTValidationOptions) + + +### KeyBindingJWTValidationOptions.fromJSON(json) ⇒ [KeyBindingJWTValidationOptions](#KeyBindingJWTValidationOptions) +Deserializes an instance from a JSON object. + +**Kind**: static method of [KeyBindingJWTValidationOptions](#KeyBindingJWTValidationOptions) + +| Param | Type | +| --- | --- | +| json | any | + + + +## KeyBindingJwtClaims +Claims set for key binding JWT. + +**Kind**: global class + +* [KeyBindingJwtClaims](#KeyBindingJwtClaims) + * [new KeyBindingJwtClaims(jwt, disclosures, nonce, aud, [issued_at], [custom_properties])](#new_KeyBindingJwtClaims_new) + * _instance_ + * [.toString()](#KeyBindingJwtClaims+toString) ⇒ string + * [.iat()](#KeyBindingJwtClaims+iat) ⇒ bigint + * [.aud()](#KeyBindingJwtClaims+aud) ⇒ string + * [.nonce()](#KeyBindingJwtClaims+nonce) ⇒ string + * [.sdHash()](#KeyBindingJwtClaims+sdHash) ⇒ string + * [.customProperties()](#KeyBindingJwtClaims+customProperties) ⇒ Record.<string, any> + * [.toJSON()](#KeyBindingJwtClaims+toJSON) ⇒ any + * [.clone()](#KeyBindingJwtClaims+clone) ⇒ [KeyBindingJwtClaims](#KeyBindingJwtClaims) + * _static_ + * [.keyBindingJwtHeaderTyp()](#KeyBindingJwtClaims.keyBindingJwtHeaderTyp) ⇒ string + * [.fromJSON(json)](#KeyBindingJwtClaims.fromJSON) ⇒ [KeyBindingJwtClaims](#KeyBindingJwtClaims) + + + +### new KeyBindingJwtClaims(jwt, disclosures, nonce, aud, [issued_at], [custom_properties]) +Creates a new [`KeyBindingJwtClaims`]. +When `issued_at` is left as None, it will automatically default to the current time. + +# Error +When `issued_at` is set to `None` and the system returns time earlier than `SystemTime::UNIX_EPOCH`. + + +| Param | Type | +| --- | --- | +| jwt | string | +| disclosures | Array.<string> | +| nonce | string | +| aud | string | +| [issued_at] | [Timestamp](#Timestamp) \| undefined | +| [custom_properties] | Record.<string, any> \| undefined | + + + +### keyBindingJwtClaims.toString() ⇒ string +Returns a string representation of the claims. + +**Kind**: instance method of [KeyBindingJwtClaims](#KeyBindingJwtClaims) + + +### keyBindingJwtClaims.iat() ⇒ bigint +Returns a copy of the issued at `iat` property. + +**Kind**: instance method of [KeyBindingJwtClaims](#KeyBindingJwtClaims) + + +### keyBindingJwtClaims.aud() ⇒ string +Returns a copy of the audience `aud` property. + +**Kind**: instance method of [KeyBindingJwtClaims](#KeyBindingJwtClaims) + + +### keyBindingJwtClaims.nonce() ⇒ string +Returns a copy of the `nonce` property. + +**Kind**: instance method of [KeyBindingJwtClaims](#KeyBindingJwtClaims) + + +### keyBindingJwtClaims.sdHash() ⇒ string +Returns a copy of the `sd_hash` property. + +**Kind**: instance method of [KeyBindingJwtClaims](#KeyBindingJwtClaims) + + +### keyBindingJwtClaims.customProperties() ⇒ Record.<string, any> +Returns a copy of the custom properties. + +**Kind**: instance method of [KeyBindingJwtClaims](#KeyBindingJwtClaims) + + +### keyBindingJwtClaims.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [KeyBindingJwtClaims](#KeyBindingJwtClaims) + + +### keyBindingJwtClaims.clone() ⇒ [KeyBindingJwtClaims](#KeyBindingJwtClaims) +Deep clones the object. + +**Kind**: instance method of [KeyBindingJwtClaims](#KeyBindingJwtClaims) + + +### KeyBindingJwtClaims.keyBindingJwtHeaderTyp() ⇒ string +Returns the value of the `typ` property of the JWT header according to +https://www.ietf.org/archive/id/draft-ietf-oauth-selective-disclosure-jwt-07.html#name-key-binding-jwt + +**Kind**: static method of [KeyBindingJwtClaims](#KeyBindingJwtClaims) + + +### KeyBindingJwtClaims.fromJSON(json) ⇒ [KeyBindingJwtClaims](#KeyBindingJwtClaims) +Deserializes an instance from a JSON object. + +**Kind**: static method of [KeyBindingJwtClaims](#KeyBindingJwtClaims) + +| Param | Type | +| --- | --- | +| json | any | + + + +## LinkedDomainService +**Kind**: global class + +* [LinkedDomainService](#LinkedDomainService) + * [new LinkedDomainService(options)](#new_LinkedDomainService_new) + * _instance_ + * [.domains()](#LinkedDomainService+domains) ⇒ Array.<string> + * [.toService()](#LinkedDomainService+toService) ⇒ [Service](#Service) + * [.clone()](#LinkedDomainService+clone) ⇒ [LinkedDomainService](#LinkedDomainService) + * _static_ + * [.fromService(service)](#LinkedDomainService.fromService) ⇒ [LinkedDomainService](#LinkedDomainService) + * [.isValid(service)](#LinkedDomainService.isValid) ⇒ boolean + + + +### new LinkedDomainService(options) +Constructs a new [LinkedDomainService](#LinkedDomainService) that wraps a spec compliant [Linked Domain Service Endpoint](https://identity.foundation/.well-known/resources/did-configuration/#linked-domain-service-endpoint). + +Domain URLs must include the `https` scheme in order to pass the domain linkage validation. + + +| Param | Type | +| --- | --- | +| options | ILinkedDomainService | + + + +### linkedDomainService.domains() ⇒ Array.<string> +Returns the domains contained in the Linked Domain Service. + +**Kind**: instance method of [LinkedDomainService](#LinkedDomainService) + + +### linkedDomainService.toService() ⇒ [Service](#Service) +Returns the inner service which can be added to a DID Document. + +**Kind**: instance method of [LinkedDomainService](#LinkedDomainService) + + +### linkedDomainService.clone() ⇒ [LinkedDomainService](#LinkedDomainService) +Deep clones the object. + +**Kind**: instance method of [LinkedDomainService](#LinkedDomainService) + + +### LinkedDomainService.fromService(service) ⇒ [LinkedDomainService](#LinkedDomainService) +Creates a new [LinkedDomainService](#LinkedDomainService) from a [Service](#Service). + +# Error + +Errors if `service` is not a valid Linked Domain Service. + +**Kind**: static method of [LinkedDomainService](#LinkedDomainService) + +| Param | Type | +| --- | --- | +| service | [Service](#Service) | + + + +### LinkedDomainService.isValid(service) ⇒ boolean +Returns `true` if a [Service](#Service) is a valid Linked Domain Service. + +**Kind**: static method of [LinkedDomainService](#LinkedDomainService) + +| Param | Type | +| --- | --- | +| service | [Service](#Service) | + + + +## MethodData +Supported verification method data formats. + +**Kind**: global class + +* [MethodData](#MethodData) + * _instance_ + * [.tryCustom()](#MethodData+tryCustom) ⇒ [CustomMethodData](#CustomMethodData) + * [.tryDecode()](#MethodData+tryDecode) ⇒ Uint8Array + * [.tryPublicKeyJwk()](#MethodData+tryPublicKeyJwk) ⇒ [Jwk](#Jwk) + * [.toJSON()](#MethodData+toJSON) ⇒ any + * [.clone()](#MethodData+clone) ⇒ [MethodData](#MethodData) + * _static_ + * [.newBase58(data)](#MethodData.newBase58) ⇒ [MethodData](#MethodData) + * [.newMultibase(data)](#MethodData.newMultibase) ⇒ [MethodData](#MethodData) + * [.newJwk(key)](#MethodData.newJwk) ⇒ [MethodData](#MethodData) + * [.newCustom(name, data)](#MethodData.newCustom) ⇒ [MethodData](#MethodData) + * [.fromJSON(json)](#MethodData.fromJSON) ⇒ [MethodData](#MethodData) + + + +### methodData.tryCustom() ⇒ [CustomMethodData](#CustomMethodData) +Returns the wrapped custom method data format is `Custom`. + +**Kind**: instance method of [MethodData](#MethodData) + + +### methodData.tryDecode() ⇒ Uint8Array +Returns a `Uint8Array` containing the decoded bytes of the [MethodData](#MethodData). + +This is generally a public key identified by a [MethodData](#MethodData) value. + +### Errors +Decoding can fail if [MethodData](#MethodData) has invalid content or cannot be +represented as a vector of bytes. + +**Kind**: instance method of [MethodData](#MethodData) + + +### methodData.tryPublicKeyJwk() ⇒ [Jwk](#Jwk) +Returns the wrapped [Jwk](#Jwk) if the format is `PublicKeyJwk`. + +**Kind**: instance method of [MethodData](#MethodData) + + +### methodData.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [MethodData](#MethodData) + + +### methodData.clone() ⇒ [MethodData](#MethodData) +Deep clones the object. + +**Kind**: instance method of [MethodData](#MethodData) + + +### MethodData.newBase58(data) ⇒ [MethodData](#MethodData) +Creates a new [MethodData](#MethodData) variant with Base58-BTC encoded content. + +**Kind**: static method of [MethodData](#MethodData) + +| Param | Type | +| --- | --- | +| data | Uint8Array | + + + +### MethodData.newMultibase(data) ⇒ [MethodData](#MethodData) +Creates a new [MethodData](#MethodData) variant with Multibase-encoded content. + +**Kind**: static method of [MethodData](#MethodData) + +| Param | Type | +| --- | --- | +| data | Uint8Array | + + + +### MethodData.newJwk(key) ⇒ [MethodData](#MethodData) +Creates a new [MethodData](#MethodData) variant consisting of the given `key`. + +### Errors +An error is thrown if the given `key` contains any private components. + +**Kind**: static method of [MethodData](#MethodData) + +| Param | Type | +| --- | --- | +| key | [Jwk](#Jwk) | + + + +### MethodData.newCustom(name, data) ⇒ [MethodData](#MethodData) +Creates a new custom [MethodData](#MethodData). + +**Kind**: static method of [MethodData](#MethodData) + +| Param | Type | +| --- | --- | +| name | string | +| data | any | + + + +### MethodData.fromJSON(json) ⇒ [MethodData](#MethodData) +Deserializes an instance from a JSON object. + +**Kind**: static method of [MethodData](#MethodData) + +| Param | Type | +| --- | --- | +| json | any | + + + +## MethodDigest +Unique identifier of a [VerificationMethod](#VerificationMethod). + +NOTE: +This class does not have a JSON representation, +use the methods `pack` and `unpack` instead. + +**Kind**: global class + +* [MethodDigest](#MethodDigest) + * [new MethodDigest(verification_method)](#new_MethodDigest_new) + * _instance_ + * [.pack()](#MethodDigest+pack) ⇒ Uint8Array + * [.clone()](#MethodDigest+clone) ⇒ [MethodDigest](#MethodDigest) + * _static_ + * [.unpack(bytes)](#MethodDigest.unpack) ⇒ [MethodDigest](#MethodDigest) + + + +### new MethodDigest(verification_method) + +| Param | Type | +| --- | --- | +| verification_method | [VerificationMethod](#VerificationMethod) | + + + +### methodDigest.pack() ⇒ Uint8Array +Packs [MethodDigest](#MethodDigest) into bytes. + +**Kind**: instance method of [MethodDigest](#MethodDigest) + + +### methodDigest.clone() ⇒ [MethodDigest](#MethodDigest) +Deep clones the object. + +**Kind**: instance method of [MethodDigest](#MethodDigest) + + +### MethodDigest.unpack(bytes) ⇒ [MethodDigest](#MethodDigest) +Unpacks bytes into [MethodDigest](#MethodDigest). + +**Kind**: static method of [MethodDigest](#MethodDigest) + +| Param | Type | +| --- | --- | +| bytes | Uint8Array | + + + +## MethodScope +Supported verification method types. + +**Kind**: global class + +* [MethodScope](#MethodScope) + * _instance_ + * [.toString()](#MethodScope+toString) ⇒ string + * [.toJSON()](#MethodScope+toJSON) ⇒ any + * [.clone()](#MethodScope+clone) ⇒ [MethodScope](#MethodScope) + * _static_ + * [.VerificationMethod()](#MethodScope.VerificationMethod) ⇒ [MethodScope](#MethodScope) + * [.Authentication()](#MethodScope.Authentication) ⇒ [MethodScope](#MethodScope) + * [.AssertionMethod()](#MethodScope.AssertionMethod) ⇒ [MethodScope](#MethodScope) + * [.KeyAgreement()](#MethodScope.KeyAgreement) ⇒ [MethodScope](#MethodScope) + * [.CapabilityDelegation()](#MethodScope.CapabilityDelegation) ⇒ [MethodScope](#MethodScope) + * [.CapabilityInvocation()](#MethodScope.CapabilityInvocation) ⇒ [MethodScope](#MethodScope) + * [.fromJSON(json)](#MethodScope.fromJSON) ⇒ [MethodScope](#MethodScope) + + + +### methodScope.toString() ⇒ string +Returns the [MethodScope](#MethodScope) as a string. + +**Kind**: instance method of [MethodScope](#MethodScope) + + +### methodScope.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [MethodScope](#MethodScope) + + +### methodScope.clone() ⇒ [MethodScope](#MethodScope) +Deep clones the object. + +**Kind**: instance method of [MethodScope](#MethodScope) + + +### MethodScope.VerificationMethod() ⇒ [MethodScope](#MethodScope) +**Kind**: static method of [MethodScope](#MethodScope) + + +### MethodScope.Authentication() ⇒ [MethodScope](#MethodScope) +**Kind**: static method of [MethodScope](#MethodScope) + + +### MethodScope.AssertionMethod() ⇒ [MethodScope](#MethodScope) +**Kind**: static method of [MethodScope](#MethodScope) + + +### MethodScope.KeyAgreement() ⇒ [MethodScope](#MethodScope) +**Kind**: static method of [MethodScope](#MethodScope) + + +### MethodScope.CapabilityDelegation() ⇒ [MethodScope](#MethodScope) +**Kind**: static method of [MethodScope](#MethodScope) + + +### MethodScope.CapabilityInvocation() ⇒ [MethodScope](#MethodScope) +**Kind**: static method of [MethodScope](#MethodScope) + + +### MethodScope.fromJSON(json) ⇒ [MethodScope](#MethodScope) +Deserializes an instance from a JSON object. + +**Kind**: static method of [MethodScope](#MethodScope) + +| Param | Type | +| --- | --- | +| json | any | + + + +## MethodType +Supported verification method types. + +**Kind**: global class + +* [MethodType](#MethodType) + * _instance_ + * [.toString()](#MethodType+toString) ⇒ string + * [.toJSON()](#MethodType+toJSON) ⇒ any + * [.clone()](#MethodType+clone) ⇒ [MethodType](#MethodType) + * _static_ + * [.Ed25519VerificationKey2018()](#MethodType.Ed25519VerificationKey2018) ⇒ [MethodType](#MethodType) + * [.X25519KeyAgreementKey2019()](#MethodType.X25519KeyAgreementKey2019) ⇒ [MethodType](#MethodType) + * ~~[.JsonWebKey()](#MethodType.JsonWebKey)~~ + * [.JsonWebKey2020()](#MethodType.JsonWebKey2020) ⇒ [MethodType](#MethodType) + * [.custom(type_)](#MethodType.custom) ⇒ [MethodType](#MethodType) + * [.fromJSON(json)](#MethodType.fromJSON) ⇒ [MethodType](#MethodType) + + + +### methodType.toString() ⇒ string +Returns the [MethodType](#MethodType) as a string. + +**Kind**: instance method of [MethodType](#MethodType) + + +### methodType.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [MethodType](#MethodType) + + +### methodType.clone() ⇒ [MethodType](#MethodType) +Deep clones the object. + +**Kind**: instance method of [MethodType](#MethodType) + + +### MethodType.Ed25519VerificationKey2018() ⇒ [MethodType](#MethodType) +**Kind**: static method of [MethodType](#MethodType) + + +### MethodType.X25519KeyAgreementKey2019() ⇒ [MethodType](#MethodType) +**Kind**: static method of [MethodType](#MethodType) + + +### ~~MethodType.JsonWebKey()~~ +***Deprecated*** + +**Kind**: static method of [MethodType](#MethodType) + + +### MethodType.JsonWebKey2020() ⇒ [MethodType](#MethodType) +A verification method for use with JWT verification as prescribed by the [Jwk](#Jwk) +in the `publicKeyJwk` entry. + +**Kind**: static method of [MethodType](#MethodType) + + +### MethodType.custom(type_) ⇒ [MethodType](#MethodType) +A custom method. + +**Kind**: static method of [MethodType](#MethodType) + +| Param | Type | +| --- | --- | +| type_ | string | + + + +### MethodType.fromJSON(json) ⇒ [MethodType](#MethodType) +Deserializes an instance from a JSON object. + +**Kind**: static method of [MethodType](#MethodType) + +| Param | Type | +| --- | --- | +| json | any | + + + +## PayloadEntry +**Kind**: global class + +* [PayloadEntry](#PayloadEntry) + * [.1](#PayloadEntry+1) ⇒ [PayloadType](#PayloadType) + * [.1](#PayloadEntry+1) + * [.value](#PayloadEntry+value) + * [.value](#PayloadEntry+value) ⇒ any + + + +### payloadEntry.1 ⇒ [PayloadType](#PayloadType) +**Kind**: instance property of [PayloadEntry](#PayloadEntry) + + +### payloadEntry.1 +**Kind**: instance property of [PayloadEntry](#PayloadEntry) + +| Param | Type | +| --- | --- | +| arg0 | [PayloadType](#PayloadType) | + + + +### payloadEntry.value +**Kind**: instance property of [PayloadEntry](#PayloadEntry) + +| Param | Type | +| --- | --- | +| value | any | + + + +### payloadEntry.value ⇒ any +**Kind**: instance property of [PayloadEntry](#PayloadEntry) + + +## Payloads +**Kind**: global class + +* [Payloads](#Payloads) + * [new Payloads(entries)](#new_Payloads_new) + * _instance_ + * [.toJSON()](#Payloads+toJSON) ⇒ any + * [.clone()](#Payloads+clone) ⇒ [Payloads](#Payloads) + * [.getValues()](#Payloads+getValues) ⇒ Array.<any> + * [.getUndisclosedIndexes()](#Payloads+getUndisclosedIndexes) ⇒ Uint32Array + * [.getDisclosedIndexes()](#Payloads+getDisclosedIndexes) ⇒ Uint32Array + * [.getUndisclosedPayloads()](#Payloads+getUndisclosedPayloads) ⇒ Array.<any> + * [.getDisclosedPayloads()](#Payloads+getDisclosedPayloads) ⇒ [Payloads](#Payloads) + * [.setUndisclosed(index)](#Payloads+setUndisclosed) + * [.replacePayloadAtIndex(index, value)](#Payloads+replacePayloadAtIndex) ⇒ any + * _static_ + * [.fromJSON(json)](#Payloads.fromJSON) ⇒ [Payloads](#Payloads) + * [.newFromValues(values)](#Payloads.newFromValues) ⇒ [Payloads](#Payloads) + + + +### new Payloads(entries) + +| Param | Type | +| --- | --- | +| entries | [Array.<PayloadEntry>](#PayloadEntry) | + + + +### payloads.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [Payloads](#Payloads) + + +### payloads.clone() ⇒ [Payloads](#Payloads) +Deep clones the object. + +**Kind**: instance method of [Payloads](#Payloads) + + +### payloads.getValues() ⇒ Array.<any> +**Kind**: instance method of [Payloads](#Payloads) + + +### payloads.getUndisclosedIndexes() ⇒ Uint32Array +**Kind**: instance method of [Payloads](#Payloads) + + +### payloads.getDisclosedIndexes() ⇒ Uint32Array +**Kind**: instance method of [Payloads](#Payloads) + + +### payloads.getUndisclosedPayloads() ⇒ Array.<any> +**Kind**: instance method of [Payloads](#Payloads) + + +### payloads.getDisclosedPayloads() ⇒ [Payloads](#Payloads) +**Kind**: instance method of [Payloads](#Payloads) + + +### payloads.setUndisclosed(index) +**Kind**: instance method of [Payloads](#Payloads) + +| Param | Type | +| --- | --- | +| index | number | + + + +### payloads.replacePayloadAtIndex(index, value) ⇒ any +**Kind**: instance method of [Payloads](#Payloads) + +| Param | Type | +| --- | --- | +| index | number | +| value | any | + + + +### Payloads.fromJSON(json) ⇒ [Payloads](#Payloads) +Deserializes an instance from a JSON object. + +**Kind**: static method of [Payloads](#Payloads) + +| Param | Type | +| --- | --- | +| json | any | + + + +### Payloads.newFromValues(values) ⇒ [Payloads](#Payloads) +**Kind**: static method of [Payloads](#Payloads) + +| Param | Type | +| --- | --- | +| values | Array.<any> | + + + +## Presentation +**Kind**: global class + +* [Presentation](#Presentation) + * [new Presentation(values)](#new_Presentation_new) + * _instance_ + * [.context()](#Presentation+context) ⇒ Array.<(string\|Record.<string, any>)> + * [.id()](#Presentation+id) ⇒ string \| undefined + * [.type()](#Presentation+type) ⇒ Array.<string> + * [.verifiableCredential()](#Presentation+verifiableCredential) ⇒ [Array.<UnknownCredential>](#UnknownCredential) + * [.holder()](#Presentation+holder) ⇒ string + * [.refreshService()](#Presentation+refreshService) ⇒ Array.<RefreshService> + * [.termsOfUse()](#Presentation+termsOfUse) ⇒ Array.<Policy> + * [.proof()](#Presentation+proof) ⇒ [Proof](#Proof) \| undefined + * [.setProof([proof])](#Presentation+setProof) + * [.properties()](#Presentation+properties) ⇒ Map.<string, any> + * [.toJSON()](#Presentation+toJSON) ⇒ any + * [.clone()](#Presentation+clone) ⇒ [Presentation](#Presentation) + * _static_ + * [.BaseContext()](#Presentation.BaseContext) ⇒ string + * [.BaseType()](#Presentation.BaseType) ⇒ string + * [.fromJSON(json)](#Presentation.fromJSON) ⇒ [Presentation](#Presentation) + + + +### new Presentation(values) +Constructs a new presentation. + + +| Param | Type | +| --- | --- | +| values | IPresentation | + + + +### presentation.context() ⇒ Array.<(string\|Record.<string, any>)> +Returns a copy of the JSON-LD context(s) applicable to the presentation. + +**Kind**: instance method of [Presentation](#Presentation) + + +### presentation.id() ⇒ string \| undefined +Returns a copy of the unique `URI` identifying the presentation. + +**Kind**: instance method of [Presentation](#Presentation) + + +### presentation.type() ⇒ Array.<string> +Returns a copy of the URIs defining the type of the presentation. + +**Kind**: instance method of [Presentation](#Presentation) + + +### presentation.verifiableCredential() ⇒ [Array.<UnknownCredential>](#UnknownCredential) +Returns the JWT credentials expressing the claims of the presentation. + +**Kind**: instance method of [Presentation](#Presentation) + + +### presentation.holder() ⇒ string +Returns a copy of the URI of the entity that generated the presentation. + +**Kind**: instance method of [Presentation](#Presentation) + + +### presentation.refreshService() ⇒ Array.<RefreshService> +Returns a copy of the service(s) used to refresh an expired [Credential](#Credential) in the presentation. + +**Kind**: instance method of [Presentation](#Presentation) + + +### presentation.termsOfUse() ⇒ Array.<Policy> +Returns a copy of the terms-of-use specified by the presentation holder + +**Kind**: instance method of [Presentation](#Presentation) + + +### presentation.proof() ⇒ [Proof](#Proof) \| undefined +Optional cryptographic proof, unrelated to JWT. + +**Kind**: instance method of [Presentation](#Presentation) + + +### presentation.setProof([proof]) +Sets the proof property of the [Presentation](#Presentation). + +Note that this proof is not related to JWT. + +**Kind**: instance method of [Presentation](#Presentation) + +| Param | Type | +| --- | --- | +| [proof] | [Proof](#Proof) \| undefined | + + + +### presentation.properties() ⇒ Map.<string, any> +Returns a copy of the miscellaneous properties on the presentation. + +**Kind**: instance method of [Presentation](#Presentation) + + +### presentation.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [Presentation](#Presentation) + + +### presentation.clone() ⇒ [Presentation](#Presentation) +Deep clones the object. + +**Kind**: instance method of [Presentation](#Presentation) + + +### Presentation.BaseContext() ⇒ string +Returns the base JSON-LD context. + +**Kind**: static method of [Presentation](#Presentation) + + +### Presentation.BaseType() ⇒ string +Returns the base type. + +**Kind**: static method of [Presentation](#Presentation) + + +### Presentation.fromJSON(json) ⇒ [Presentation](#Presentation) +Deserializes an instance from a JSON object. + +**Kind**: static method of [Presentation](#Presentation) + +| Param | Type | +| --- | --- | +| json | any | + + + +## PresentationProtectedHeader +**Kind**: global class + +* [PresentationProtectedHeader](#PresentationProtectedHeader) + * [.alg](#PresentationProtectedHeader+alg) ⇒ [PresentationProofAlgorithm](#PresentationProofAlgorithm) + * [.alg](#PresentationProtectedHeader+alg) + * [.kid](#PresentationProtectedHeader+kid) ⇒ string \| undefined + * [.kid](#PresentationProtectedHeader+kid) + * [.aud](#PresentationProtectedHeader+aud) ⇒ string \| undefined + * [.aud](#PresentationProtectedHeader+aud) + * [.nonce](#PresentationProtectedHeader+nonce) ⇒ string \| undefined + * [.nonce](#PresentationProtectedHeader+nonce) + + + +### presentationProtectedHeader.alg ⇒ [PresentationProofAlgorithm](#PresentationProofAlgorithm) +**Kind**: instance property of [PresentationProtectedHeader](#PresentationProtectedHeader) + + +### presentationProtectedHeader.alg +**Kind**: instance property of [PresentationProtectedHeader](#PresentationProtectedHeader) + +| Param | Type | +| --- | --- | +| arg0 | [PresentationProofAlgorithm](#PresentationProofAlgorithm) | + + + +### presentationProtectedHeader.kid ⇒ string \| undefined +ID for the key used for the JWP. + +**Kind**: instance property of [PresentationProtectedHeader](#PresentationProtectedHeader) + + +### presentationProtectedHeader.kid +ID for the key used for the JWP. + +**Kind**: instance property of [PresentationProtectedHeader](#PresentationProtectedHeader) + +| Param | Type | +| --- | --- | +| [arg0] | string \| undefined | + + + +### presentationProtectedHeader.aud ⇒ string \| undefined +Who have received the JPT. + +**Kind**: instance property of [PresentationProtectedHeader](#PresentationProtectedHeader) + + +### presentationProtectedHeader.aud +Who have received the JPT. + +**Kind**: instance property of [PresentationProtectedHeader](#PresentationProtectedHeader) + +| Param | Type | +| --- | --- | +| [arg0] | string \| undefined | + + + +### presentationProtectedHeader.nonce ⇒ string \| undefined +For replay attacks. + +**Kind**: instance property of [PresentationProtectedHeader](#PresentationProtectedHeader) + + +### presentationProtectedHeader.nonce +For replay attacks. + +**Kind**: instance property of [PresentationProtectedHeader](#PresentationProtectedHeader) + +| Param | Type | +| --- | --- | +| [arg0] | string \| undefined | + + + +## Proof +Represents a cryptographic proof that can be used to validate verifiable credentials and +presentations. + +This representation does not inherently implement any standard; instead, it +can be utilized to implement standards or user-defined proofs. The presence of the +`type` field is necessary to accommodate different types of cryptographic proofs. + +Note that this proof is not related to JWT and can be used in combination or as an alternative +to it. + +**Kind**: global class + +* [Proof](#Proof) + * [new Proof(type_, properties)](#new_Proof_new) + * _instance_ + * [.type()](#Proof+type) ⇒ string + * [.properties()](#Proof+properties) ⇒ any + * [.toJSON()](#Proof+toJSON) ⇒ any + * [.clone()](#Proof+clone) ⇒ [Proof](#Proof) + * _static_ + * [.fromJSON(json)](#Proof.fromJSON) ⇒ [Proof](#Proof) + + + +### new Proof(type_, properties) + +| Param | Type | +| --- | --- | +| type_ | string | +| properties | any | + + + +### proof.type() ⇒ string +Returns the type of proof. + +**Kind**: instance method of [Proof](#Proof) + + +### proof.properties() ⇒ any +Returns the properties of the proof. + +**Kind**: instance method of [Proof](#Proof) + + +### proof.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [Proof](#Proof) + + +### proof.clone() ⇒ [Proof](#Proof) +Deep clones the object. + +**Kind**: instance method of [Proof](#Proof) + + +### Proof.fromJSON(json) ⇒ [Proof](#Proof) +Deserializes an instance from a JSON object. + +**Kind**: static method of [Proof](#Proof) + +| Param | Type | +| --- | --- | +| json | any | + + + +## ProofUpdateCtx +**Kind**: global class + +* [ProofUpdateCtx](#ProofUpdateCtx) + * [.old_start_validity_timeframe](#ProofUpdateCtx+old_start_validity_timeframe) ⇒ Uint8Array + * [.old_start_validity_timeframe](#ProofUpdateCtx+old_start_validity_timeframe) + * [.new_start_validity_timeframe](#ProofUpdateCtx+new_start_validity_timeframe) ⇒ Uint8Array + * [.new_start_validity_timeframe](#ProofUpdateCtx+new_start_validity_timeframe) + * [.old_end_validity_timeframe](#ProofUpdateCtx+old_end_validity_timeframe) ⇒ Uint8Array + * [.old_end_validity_timeframe](#ProofUpdateCtx+old_end_validity_timeframe) + * [.new_end_validity_timeframe](#ProofUpdateCtx+new_end_validity_timeframe) ⇒ Uint8Array + * [.new_end_validity_timeframe](#ProofUpdateCtx+new_end_validity_timeframe) + * [.index_start_validity_timeframe](#ProofUpdateCtx+index_start_validity_timeframe) ⇒ number + * [.index_start_validity_timeframe](#ProofUpdateCtx+index_start_validity_timeframe) + * [.index_end_validity_timeframe](#ProofUpdateCtx+index_end_validity_timeframe) ⇒ number + * [.index_end_validity_timeframe](#ProofUpdateCtx+index_end_validity_timeframe) + * [.number_of_signed_messages](#ProofUpdateCtx+number_of_signed_messages) ⇒ number + * [.number_of_signed_messages](#ProofUpdateCtx+number_of_signed_messages) + + + +### proofUpdateCtx.old\_start\_validity\_timeframe ⇒ Uint8Array +Old `startValidityTimeframe` value + +**Kind**: instance property of [ProofUpdateCtx](#ProofUpdateCtx) + + +### proofUpdateCtx.old\_start\_validity\_timeframe +Old `startValidityTimeframe` value + +**Kind**: instance property of [ProofUpdateCtx](#ProofUpdateCtx) + +| Param | Type | +| --- | --- | +| arg0 | Uint8Array | + + + +### proofUpdateCtx.new\_start\_validity\_timeframe ⇒ Uint8Array +New `startValidityTimeframe` value to be signed + +**Kind**: instance property of [ProofUpdateCtx](#ProofUpdateCtx) + + +### proofUpdateCtx.new\_start\_validity\_timeframe +New `startValidityTimeframe` value to be signed + +**Kind**: instance property of [ProofUpdateCtx](#ProofUpdateCtx) + +| Param | Type | +| --- | --- | +| arg0 | Uint8Array | + + + +### proofUpdateCtx.old\_end\_validity\_timeframe ⇒ Uint8Array +Old `endValidityTimeframe` value + +**Kind**: instance property of [ProofUpdateCtx](#ProofUpdateCtx) + + +### proofUpdateCtx.old\_end\_validity\_timeframe +Old `endValidityTimeframe` value + +**Kind**: instance property of [ProofUpdateCtx](#ProofUpdateCtx) + +| Param | Type | +| --- | --- | +| arg0 | Uint8Array | + + + +### proofUpdateCtx.new\_end\_validity\_timeframe ⇒ Uint8Array +New `endValidityTimeframe` value to be signed + +**Kind**: instance property of [ProofUpdateCtx](#ProofUpdateCtx) + + +### proofUpdateCtx.new\_end\_validity\_timeframe +New `endValidityTimeframe` value to be signed + +**Kind**: instance property of [ProofUpdateCtx](#ProofUpdateCtx) + +| Param | Type | +| --- | --- | +| arg0 | Uint8Array | + + + +### proofUpdateCtx.index\_start\_validity\_timeframe ⇒ number +Index of `startValidityTimeframe` claim inside the array of Claims + +**Kind**: instance property of [ProofUpdateCtx](#ProofUpdateCtx) + + +### proofUpdateCtx.index\_start\_validity\_timeframe +Index of `startValidityTimeframe` claim inside the array of Claims + +**Kind**: instance property of [ProofUpdateCtx](#ProofUpdateCtx) + +| Param | Type | +| --- | --- | +| arg0 | number | + + + +### proofUpdateCtx.index\_end\_validity\_timeframe ⇒ number +Index of `endValidityTimeframe` claim inside the array of Claims + +**Kind**: instance property of [ProofUpdateCtx](#ProofUpdateCtx) + + +### proofUpdateCtx.index\_end\_validity\_timeframe +Index of `endValidityTimeframe` claim inside the array of Claims + +**Kind**: instance property of [ProofUpdateCtx](#ProofUpdateCtx) + +| Param | Type | +| --- | --- | +| arg0 | number | + + + +### proofUpdateCtx.number\_of\_signed\_messages ⇒ number +Number of signed messages, number of payloads in a JWP + +**Kind**: instance property of [ProofUpdateCtx](#ProofUpdateCtx) + + +### proofUpdateCtx.number\_of\_signed\_messages +Number of signed messages, number of payloads in a JWP + +**Kind**: instance property of [ProofUpdateCtx](#ProofUpdateCtx) + +| Param | Type | +| --- | --- | +| arg0 | number | + + + +## Resolver +Convenience type for resolving DID documents from different DID methods. + +Also provides methods for resolving DID Documents associated with +verifiable [Credential](#Credential)s and [Presentation](#Presentation)s. + +# Configuration + +The resolver will only be able to resolve DID documents for methods it has been configured for in the constructor. + +**Kind**: global class + +* [Resolver](#Resolver) + * [new Resolver(config)](#new_Resolver_new) + * [.resolve(did)](#Resolver+resolve) ⇒ Promise.<(CoreDocument\|IToCoreDocument)> + * [.resolveMultiple(dids)](#Resolver+resolveMultiple) ⇒ Promise.<Array.<(CoreDocument\|IToCoreDocument)>> + + + +### new Resolver(config) +Constructs a new [Resolver](#Resolver). + +# Errors +If both a `client` is given and the `handlers` map contains the "iota" key the construction process +will throw an error because the handler for the "iota" method then becomes ambiguous. + + +| Param | Type | +| --- | --- | +| config | ResolverConfig | + + + +### resolver.resolve(did) ⇒ Promise.<(CoreDocument\|IToCoreDocument)> +Fetches the DID Document of the given DID. + +### Errors + +Errors if the resolver has not been configured to handle the method +corresponding to the given DID or the resolution process itself fails. + +**Kind**: instance method of [Resolver](#Resolver) + +| Param | Type | +| --- | --- | +| did | string | + + + +### resolver.resolveMultiple(dids) ⇒ Promise.<Array.<(CoreDocument\|IToCoreDocument)>> +Concurrently fetches the DID Documents of the multiple given DIDs. + +# Errors +* If the resolver has not been configured to handle the method of any of the given DIDs. +* If the resolution process of any DID fails. + +## Note +* The order of the documents in the returned array matches that in `dids`. +* If `dids` contains duplicates, these will be resolved only once and the resolved document +is copied into the returned array to match the order of `dids`. + +**Kind**: instance method of [Resolver](#Resolver) + +| Param | Type | +| --- | --- | +| dids | Array.<string> | + + + +## RevocationBitmap +A compressed bitmap for managing credential revocation. + +**Kind**: global class + +* [RevocationBitmap](#RevocationBitmap) + * [new RevocationBitmap()](#new_RevocationBitmap_new) + * _instance_ + * [.isRevoked(index)](#RevocationBitmap+isRevoked) ⇒ boolean + * [.revoke(index)](#RevocationBitmap+revoke) ⇒ boolean + * [.unrevoke(index)](#RevocationBitmap+unrevoke) ⇒ boolean + * [.len()](#RevocationBitmap+len) ⇒ number + * [.toService(serviceId)](#RevocationBitmap+toService) ⇒ [Service](#Service) + * _static_ + * [.type()](#RevocationBitmap.type) ⇒ string + * [.fromEndpoint(service)](#RevocationBitmap.fromEndpoint) ⇒ [RevocationBitmap](#RevocationBitmap) + + + +### new RevocationBitmap() +Creates a new [RevocationBitmap](#RevocationBitmap) instance. + + + +### revocationBitmap.isRevoked(index) ⇒ boolean +Returns `true` if the credential at the given `index` is revoked. + +**Kind**: instance method of [RevocationBitmap](#RevocationBitmap) + +| Param | Type | +| --- | --- | +| index | number | + + + +### revocationBitmap.revoke(index) ⇒ boolean +Mark the given index as revoked. + +Returns true if the index was absent from the set. + +**Kind**: instance method of [RevocationBitmap](#RevocationBitmap) + +| Param | Type | +| --- | --- | +| index | number | + + + +### revocationBitmap.unrevoke(index) ⇒ boolean +Mark the index as not revoked. + +Returns true if the index was present in the set. + +**Kind**: instance method of [RevocationBitmap](#RevocationBitmap) + +| Param | Type | +| --- | --- | +| index | number | + + + +### revocationBitmap.len() ⇒ number +Returns the number of revoked credentials. + +**Kind**: instance method of [RevocationBitmap](#RevocationBitmap) + + +### revocationBitmap.toService(serviceId) ⇒ [Service](#Service) +Return a `Service` with: +- the service's id set to `serviceId`, +- of type `RevocationBitmap2022`, +- and with the bitmap embedded in a data url in the service's endpoint. + +**Kind**: instance method of [RevocationBitmap](#RevocationBitmap) + +| Param | Type | +| --- | --- | +| serviceId | [DIDUrl](#DIDUrl) | + + + +### RevocationBitmap.type() ⇒ string +The name of the service type. + +**Kind**: static method of [RevocationBitmap](#RevocationBitmap) + + +### RevocationBitmap.fromEndpoint(service) ⇒ [RevocationBitmap](#RevocationBitmap) +Try to construct a [RevocationBitmap](#RevocationBitmap) from a service +if it is a valid Revocation Bitmap Service. + +**Kind**: static method of [RevocationBitmap](#RevocationBitmap) + +| Param | Type | +| --- | --- | +| service | [Service](#Service) | + + + +## RevocationTimeframeStatus +Information used to determine the current status of a [Credential](#Credential). + +**Kind**: global class + +* [RevocationTimeframeStatus](#RevocationTimeframeStatus) + * [new RevocationTimeframeStatus(id, index, duration, [start_validity])](#new_RevocationTimeframeStatus_new) + * _instance_ + * [.clone()](#RevocationTimeframeStatus+clone) ⇒ [RevocationTimeframeStatus](#RevocationTimeframeStatus) + * [.toJSON()](#RevocationTimeframeStatus+toJSON) ⇒ any + * [.startValidityTimeframe()](#RevocationTimeframeStatus+startValidityTimeframe) ⇒ [Timestamp](#Timestamp) + * [.endValidityTimeframe()](#RevocationTimeframeStatus+endValidityTimeframe) ⇒ [Timestamp](#Timestamp) + * [.id()](#RevocationTimeframeStatus+id) ⇒ string + * [.index()](#RevocationTimeframeStatus+index) ⇒ number \| undefined + * _static_ + * [.fromJSON(json)](#RevocationTimeframeStatus.fromJSON) ⇒ [RevocationTimeframeStatus](#RevocationTimeframeStatus) + + + +### new RevocationTimeframeStatus(id, index, duration, [start_validity]) +Creates a new `RevocationTimeframeStatus`. + + +| Param | Type | +| --- | --- | +| id | string | +| index | number | +| duration | [Duration](#Duration) | +| [start_validity] | [Timestamp](#Timestamp) \| undefined | + + + +### revocationTimeframeStatus.clone() ⇒ [RevocationTimeframeStatus](#RevocationTimeframeStatus) +Deep clones the object. + +**Kind**: instance method of [RevocationTimeframeStatus](#RevocationTimeframeStatus) + + +### revocationTimeframeStatus.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [RevocationTimeframeStatus](#RevocationTimeframeStatus) + + +### revocationTimeframeStatus.startValidityTimeframe() ⇒ [Timestamp](#Timestamp) +Get startValidityTimeframe value. + +**Kind**: instance method of [RevocationTimeframeStatus](#RevocationTimeframeStatus) + + +### revocationTimeframeStatus.endValidityTimeframe() ⇒ [Timestamp](#Timestamp) +Get endValidityTimeframe value. + +**Kind**: instance method of [RevocationTimeframeStatus](#RevocationTimeframeStatus) + + +### revocationTimeframeStatus.id() ⇒ string +Return the URL fo the `RevocationBitmapStatus`. + +**Kind**: instance method of [RevocationTimeframeStatus](#RevocationTimeframeStatus) + + +### revocationTimeframeStatus.index() ⇒ number \| undefined +Return the index of the credential in the issuer's revocation bitmap + +**Kind**: instance method of [RevocationTimeframeStatus](#RevocationTimeframeStatus) + + +### RevocationTimeframeStatus.fromJSON(json) ⇒ [RevocationTimeframeStatus](#RevocationTimeframeStatus) +Deserializes an instance from a JSON object. + +**Kind**: static method of [RevocationTimeframeStatus](#RevocationTimeframeStatus) + +| Param | Type | +| --- | --- | +| json | any | + + + +## SdJwt +Representation of an SD-JWT of the format +`~~~...~~`. + +**Kind**: global class + +* [SdJwt](#SdJwt) + * [new SdJwt(jwt, disclosures, [key_binding_jwt])](#new_SdJwt_new) + * _instance_ + * [.presentation()](#SdJwt+presentation) ⇒ string + * [.toString()](#SdJwt+toString) ⇒ string + * [.jwt()](#SdJwt+jwt) ⇒ string + * [.disclosures()](#SdJwt+disclosures) ⇒ Array.<string> + * [.keyBindingJwt()](#SdJwt+keyBindingJwt) ⇒ string \| undefined + * [.clone()](#SdJwt+clone) ⇒ [SdJwt](#SdJwt) + * _static_ + * [.parse(sd_jwt)](#SdJwt.parse) ⇒ [SdJwt](#SdJwt) + + + +### new SdJwt(jwt, disclosures, [key_binding_jwt]) +Creates a new `SdJwt` from its components. + + +| Param | Type | +| --- | --- | +| jwt | string | +| disclosures | Array.<string> | +| [key_binding_jwt] | string \| undefined | + + + +### sdJwt.presentation() ⇒ string +Serializes the components into the final SD-JWT. + +**Kind**: instance method of [SdJwt](#SdJwt) + + +### sdJwt.toString() ⇒ string +Serializes the components into the final SD-JWT. + +**Kind**: instance method of [SdJwt](#SdJwt) + + +### sdJwt.jwt() ⇒ string +The JWT part. + +**Kind**: instance method of [SdJwt](#SdJwt) + + +### sdJwt.disclosures() ⇒ Array.<string> +The disclosures part. + +**Kind**: instance method of [SdJwt](#SdJwt) + + +### sdJwt.keyBindingJwt() ⇒ string \| undefined +The optional key binding JWT. + +**Kind**: instance method of [SdJwt](#SdJwt) + + +### sdJwt.clone() ⇒ [SdJwt](#SdJwt) +Deep clones the object. + +**Kind**: instance method of [SdJwt](#SdJwt) + + +### SdJwt.parse(sd_jwt) ⇒ [SdJwt](#SdJwt) +Parses an SD-JWT into its components as [`SdJwt`]. + +## Error +Returns `DeserializationError` if parsing fails. + +**Kind**: static method of [SdJwt](#SdJwt) + +| Param | Type | +| --- | --- | +| sd_jwt | string | + + + +## SdJwtCredentialValidator +A type for decoding and validating [Credential](#Credential). + +**Kind**: global class + +* [SdJwtCredentialValidator](#SdJwtCredentialValidator) + * [new SdJwtCredentialValidator(signatureVerifier)](#new_SdJwtCredentialValidator_new) + * [.validateCredential(sd_jwt, issuer, options, fail_fast)](#SdJwtCredentialValidator+validateCredential) ⇒ [DecodedJwtCredential](#DecodedJwtCredential) + * [.verifySignature(credential, trustedIssuers, options)](#SdJwtCredentialValidator+verifySignature) ⇒ [DecodedJwtCredential](#DecodedJwtCredential) + * [.validateKeyBindingJwt(sdJwt, holder, options)](#SdJwtCredentialValidator+validateKeyBindingJwt) ⇒ [KeyBindingJwtClaims](#KeyBindingJwtClaims) + + + +### new SdJwtCredentialValidator(signatureVerifier) +Creates a new `SdJwtCredentialValidator`. If a `signatureVerifier` is provided it will be used when +verifying decoded JWS signatures, otherwise the default which is only capable of handling the `EdDSA` +algorithm will be used. + + +| Param | Type | +| --- | --- | +| signatureVerifier | IJwsVerifier | + + + +### sdJwtCredentialValidator.validateCredential(sd_jwt, issuer, options, fail_fast) ⇒ [DecodedJwtCredential](#DecodedJwtCredential) +Decodes and validates a `Credential` issued as an SD-JWT. A `DecodedJwtCredential` is returned upon success. +The credential is constructed by replacing disclosures following the +[`Selective Disclosure for JWTs (SD-JWT)`](https://www.ietf.org/archive/id/draft-ietf-oauth-selective-disclosure-jwt-07.html) standard. + +The following properties are validated according to `options`: +- the issuer's signature on the JWS, +- the expiration date, +- the issuance date, +- the semantic structure. + +# Warning +* The key binding JWT is not validated. If needed, it must be validated separately using +`SdJwtValidator::validate_key_binding_jwt`. +* The lack of an error returned from this method is in of itself not enough to conclude that the credential can be +trusted. This section contains more information on additional checks that should be carried out before and after +calling this method. + +## The state of the issuer's DID Document +The caller must ensure that `issuer` represents an up-to-date DID Document. + +## Properties that are not validated + There are many properties defined in [The Verifiable Credentials Data Model](https://www.w3.org/TR/vc-data-model/) that are **not** validated, such as: +`proof`, `credentialStatus`, `type`, `credentialSchema`, `refreshService` **and more**. +These should be manually checked after validation, according to your requirements. + +# Errors +An error is returned whenever a validated condition is not satisfied. + +**Kind**: instance method of [SdJwtCredentialValidator](#SdJwtCredentialValidator) + +| Param | Type | +| --- | --- | +| sd_jwt | [SdJwt](#SdJwt) | +| issuer | [CoreDocument](#CoreDocument) \| IToCoreDocument | +| options | [JwtCredentialValidationOptions](#JwtCredentialValidationOptions) | +| fail_fast | [FailFast](#FailFast) | + + + +### sdJwtCredentialValidator.verifySignature(credential, trustedIssuers, options) ⇒ [DecodedJwtCredential](#DecodedJwtCredential) +Decode and verify the JWS signature of a `Credential` issued as an SD-JWT using the DID Document of a trusted +issuer and replaces the disclosures. + +A `DecodedJwtCredential` is returned upon success. + +# Warning +The caller must ensure that the DID Documents of the trusted issuers are up-to-date. + +## Proofs + Only the JWS signature is verified. If the `Credential` contains a `proof` property this will not be verified +by this method. + +# Errors +* If the issuer' URL cannot be parsed. +* If Signature verification fails. +* If SD decoding fails. + +**Kind**: instance method of [SdJwtCredentialValidator](#SdJwtCredentialValidator) + +| Param | Type | +| --- | --- | +| credential | [SdJwt](#SdJwt) | +| trustedIssuers | Array.<(CoreDocument\|IToCoreDocument)> | +| options | [JwsVerificationOptions](#JwsVerificationOptions) | + + + +### sdJwtCredentialValidator.validateKeyBindingJwt(sdJwt, holder, options) ⇒ [KeyBindingJwtClaims](#KeyBindingJwtClaims) +Validates a Key Binding JWT (KB-JWT) according to `https://www.ietf.org/archive/id/draft-ietf-oauth-selective-disclosure-jwt-07.html#name-key-binding-jwt`. +The Validation process includes: + * Signature validation using public key materials defined in the `holder` document. + * `typ` value in KB-JWT header. + * `sd_hash` claim value in the KB-JWT claim. + * Optional `nonce`, `aud` and issuance date validation. + +**Kind**: instance method of [SdJwtCredentialValidator](#SdJwtCredentialValidator) + +| Param | Type | +| --- | --- | +| sdJwt | [SdJwt](#SdJwt) | +| holder | [CoreDocument](#CoreDocument) \| IToCoreDocument | +| options | [KeyBindingJWTValidationOptions](#KeyBindingJWTValidationOptions) | + + + +## SdObjectDecoder +Substitutes digests in an SD-JWT object by their corresponding plaintext values provided by disclosures. + +**Kind**: global class + +* [SdObjectDecoder](#SdObjectDecoder) + * [new SdObjectDecoder()](#new_SdObjectDecoder_new) + * [.decode(object, disclosures)](#SdObjectDecoder+decode) ⇒ Record.<string, any> + + + +### new SdObjectDecoder() +Creates a new `SdObjectDecoder` with `sha-256` hasher. + + + +### sdObjectDecoder.decode(object, disclosures) ⇒ Record.<string, any> +Decodes an SD-JWT `object` containing by Substituting the digests with their corresponding +plaintext values provided by `disclosures`. + +## Notes +* Claims like `exp` or `iat` are not validated in the process of decoding. +* `_sd_alg` property will be removed if present. + +**Kind**: instance method of [SdObjectDecoder](#SdObjectDecoder) + +| Param | Type | +| --- | --- | +| object | Record.<string, any> | +| disclosures | Array.<string> | + + + +## SdObjectEncoder +Transforms a JSON object into an SD-JWT object by substituting selected values +with their corresponding disclosure digests. + +Note: digests are created using the sha-256 algorithm. + +**Kind**: global class + +* [SdObjectEncoder](#SdObjectEncoder) + * [new SdObjectEncoder(object)](#new_SdObjectEncoder_new) + * [.conceal(path, [salt])](#SdObjectEncoder+conceal) ⇒ [Disclosure](#Disclosure) + * [.addSdAlgProperty()](#SdObjectEncoder+addSdAlgProperty) + * [.encodeToString()](#SdObjectEncoder+encodeToString) ⇒ string + * [.toString()](#SdObjectEncoder+toString) ⇒ string + * [.encodeToObject()](#SdObjectEncoder+encodeToObject) ⇒ Record.<string, any> + * [.toJSON()](#SdObjectEncoder+toJSON) ⇒ any + * [.addDecoys(path, number_of_decoys)](#SdObjectEncoder+addDecoys) + + + +### new SdObjectEncoder(object) +Creates a new `SdObjectEncoder` with `sha-256` hash function. + + +| Param | Type | +| --- | --- | +| object | any | + + + +### sdObjectEncoder.conceal(path, [salt]) ⇒ [Disclosure](#Disclosure) +Substitutes a value with the digest of its disclosure. +If no salt is provided, the disclosure will be created with a random salt value. + +`path` indicates the pointer to the value that will be concealed using the syntax of +[JSON pointer](https://datatracker.ietf.org/doc/html/rfc6901). + +For the following object: + + ``` +{ + "id": "did:value", + "claim1": { + "abc": true + }, + "claim2": ["val_1", "val_2"] +} +``` + +Path "/id" conceals `"id": "did:value"` +Path "/claim1/abc" conceals `"abc": true` +Path "/claim2/0" conceals `val_1` +``` + +## Errors +* `InvalidPath` if pointer is invalid. +* `DataTypeMismatch` if existing SD format is invalid. + +**Kind**: instance method of [SdObjectEncoder](#SdObjectEncoder) + +| Param | Type | +| --- | --- | +| path | string | +| [salt] | string \| undefined | + + + +### sdObjectEncoder.addSdAlgProperty() +Adds the `_sd_alg` property to the top level of the object, with +its value set to "sha-256". + +**Kind**: instance method of [SdObjectEncoder](#SdObjectEncoder) + + +### sdObjectEncoder.encodeToString() ⇒ string +Returns the modified object as a string. + +**Kind**: instance method of [SdObjectEncoder](#SdObjectEncoder) + + +### sdObjectEncoder.toString() ⇒ string +Returns the modified object as a string. + +**Kind**: instance method of [SdObjectEncoder](#SdObjectEncoder) + + +### sdObjectEncoder.encodeToObject() ⇒ Record.<string, any> +Returns the modified object. + +**Kind**: instance method of [SdObjectEncoder](#SdObjectEncoder) + + +### sdObjectEncoder.toJSON() ⇒ any +Returns the modified object. + +**Kind**: instance method of [SdObjectEncoder](#SdObjectEncoder) + + +### sdObjectEncoder.addDecoys(path, number_of_decoys) +Adds a decoy digest to the specified path. +If path is an empty slice, decoys will be added to the top level. + +**Kind**: instance method of [SdObjectEncoder](#SdObjectEncoder) + +| Param | Type | +| --- | --- | +| path | string | +| number_of_decoys | number | + + + +## SelectiveDisclosurePresentation +Used to construct a JwpPresentedBuilder and handle the selective disclosure of attributes +- @context MUST NOT be blinded +- id MUST be blinded +- type MUST NOT be blinded +- issuer MUST NOT be blinded +- issuanceDate MUST be blinded (if Timeframe Revocation mechanism is used) +- expirationDate MUST be blinded (if Timeframe Revocation mechanism is used) +- credentialSubject (User have to choose which attribute must be blinded) +- credentialSchema MUST NOT be blinded +- credentialStatus MUST NOT be blinded +- refreshService MUST NOT be blinded (probably will be used for Timeslot Revocation mechanism) +- termsOfUse NO reason to use it in ZK VC (will be in any case blinded) +- evidence (User have to choose which attribute must be blinded) + +**Kind**: global class + +* [SelectiveDisclosurePresentation](#SelectiveDisclosurePresentation) + * [new SelectiveDisclosurePresentation(issued_jwp)](#new_SelectiveDisclosurePresentation_new) + * [.concealInSubject(path)](#SelectiveDisclosurePresentation+concealInSubject) + * [.concealInEvidence(path)](#SelectiveDisclosurePresentation+concealInEvidence) + * [.setPresentationHeader(header)](#SelectiveDisclosurePresentation+setPresentationHeader) + + + +### new SelectiveDisclosurePresentation(issued_jwp) +Initialize a presentation starting from an Issued JWP. +The properties `jti`, `nbf`, `issuanceDate`, `expirationDate` and `termsOfUse` are concealed by default. + + +| Param | Type | +| --- | --- | +| issued_jwp | [JwpIssued](#JwpIssued) | + + + +### selectiveDisclosurePresentation.concealInSubject(path) +Selectively disclose "credentialSubject" attributes. +# Example +``` +{ + "id": 1234, + "name": "Alice", + "mainCourses": ["Object-oriented Programming", "Mathematics"], + "degree": { + "type": "BachelorDegree", + "name": "Bachelor of Science and Arts", + }, + "GPA": "4.0", +} +``` +If you want to undisclose for example the Mathematics course and the name of the degree: +``` +undisclose_subject("mainCourses[1]"); +undisclose_subject("degree.name"); +``` + +**Kind**: instance method of [SelectiveDisclosurePresentation](#SelectiveDisclosurePresentation) + +| Param | Type | +| --- | --- | +| path | string | + + + +### selectiveDisclosurePresentation.concealInEvidence(path) +Undiscloses "evidence" attributes. + +**Kind**: instance method of [SelectiveDisclosurePresentation](#SelectiveDisclosurePresentation) + +| Param | Type | +| --- | --- | +| path | string | + + + +### selectiveDisclosurePresentation.setPresentationHeader(header) +Sets presentation protected header. + +**Kind**: instance method of [SelectiveDisclosurePresentation](#SelectiveDisclosurePresentation) + +| Param | Type | +| --- | --- | +| header | [PresentationProtectedHeader](#PresentationProtectedHeader) | + + + +## Service +A DID Document Service used to enable trusted interactions associated with a DID subject. + +**Kind**: global class + +* [Service](#Service) + * [new Service(service)](#new_Service_new) + * _instance_ + * [.id()](#Service+id) ⇒ [DIDUrl](#DIDUrl) + * [.type()](#Service+type) ⇒ Array.<string> + * [.serviceEndpoint()](#Service+serviceEndpoint) ⇒ string \| Array.<string> \| Map.<string, Array.<string>> + * [.properties()](#Service+properties) ⇒ Map.<string, any> + * [.toJSON()](#Service+toJSON) ⇒ any + * [.clone()](#Service+clone) ⇒ [Service](#Service) + * _static_ + * [.fromJSON(json)](#Service.fromJSON) ⇒ [Service](#Service) + + + +### new Service(service) + +| Param | Type | +| --- | --- | +| service | IService | + + + +### service.id() ⇒ [DIDUrl](#DIDUrl) +Returns a copy of the [Service](#Service) id. + +**Kind**: instance method of [Service](#Service) + + +### service.type() ⇒ Array.<string> +Returns a copy of the [Service](#Service) type. + +**Kind**: instance method of [Service](#Service) + + +### service.serviceEndpoint() ⇒ string \| Array.<string> \| Map.<string, Array.<string>> +Returns a copy of the [Service](#Service) endpoint. + +**Kind**: instance method of [Service](#Service) + + +### service.properties() ⇒ Map.<string, any> +Returns a copy of the custom properties on the [Service](#Service). + +**Kind**: instance method of [Service](#Service) + + +### service.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [Service](#Service) + + +### service.clone() ⇒ [Service](#Service) +Deep clones the object. + +**Kind**: instance method of [Service](#Service) + + +### Service.fromJSON(json) ⇒ [Service](#Service) +Deserializes an instance from a JSON object. + +**Kind**: static method of [Service](#Service) + +| Param | Type | +| --- | --- | +| json | any | + + + +## StatusList2021 +StatusList2021 data structure as described in [W3C's VC status list 2021](https://www.w3.org/TR/2023/WD-vc-status-list-20230427/). + +**Kind**: global class + +* [StatusList2021](#StatusList2021) + * [new StatusList2021([size])](#new_StatusList2021_new) + * _instance_ + * [.clone()](#StatusList2021+clone) ⇒ [StatusList2021](#StatusList2021) + * [.len()](#StatusList2021+len) ⇒ number + * [.get(index)](#StatusList2021+get) ⇒ boolean + * [.set(index, value)](#StatusList2021+set) + * [.intoEncodedStr()](#StatusList2021+intoEncodedStr) ⇒ string + * _static_ + * [.fromEncodedStr(s)](#StatusList2021.fromEncodedStr) ⇒ [StatusList2021](#StatusList2021) + + + +### new StatusList2021([size]) +Creates a new [StatusList2021](#StatusList2021) of `size` entries. + + +| Param | Type | +| --- | --- | +| [size] | number \| undefined | + + + +### statusList2021.clone() ⇒ [StatusList2021](#StatusList2021) +Deep clones the object. + +**Kind**: instance method of [StatusList2021](#StatusList2021) + + +### statusList2021.len() ⇒ number +Returns the number of entries in this [StatusList2021](#StatusList2021). + +**Kind**: instance method of [StatusList2021](#StatusList2021) + + +### statusList2021.get(index) ⇒ boolean +Returns whether the entry at `index` is set. + +**Kind**: instance method of [StatusList2021](#StatusList2021) + +| Param | Type | +| --- | --- | +| index | number | + + + +### statusList2021.set(index, value) +Sets the value of the `index`-th entry. + +**Kind**: instance method of [StatusList2021](#StatusList2021) + +| Param | Type | +| --- | --- | +| index | number | +| value | boolean | + + + +### statusList2021.intoEncodedStr() ⇒ string +Encodes this [StatusList2021](#StatusList2021) into its compressed +base64 string representation. + +**Kind**: instance method of [StatusList2021](#StatusList2021) + + +### StatusList2021.fromEncodedStr(s) ⇒ [StatusList2021](#StatusList2021) +Attempts to decode a [StatusList2021](#StatusList2021) from a string. + +**Kind**: static method of [StatusList2021](#StatusList2021) + +| Param | Type | +| --- | --- | +| s | string | + + + +## StatusList2021Credential +A parsed [StatusList2021Credential](https://www.w3.org/TR/2023/WD-vc-status-list-20230427/#statuslist2021credential). + +**Kind**: global class + +* [StatusList2021Credential](#StatusList2021Credential) + * [new StatusList2021Credential(credential)](#new_StatusList2021Credential_new) + * _instance_ + * [.id()](#StatusList2021Credential+id) ⇒ string + * [.setCredentialStatus(credential, index, revoked_or_suspended)](#StatusList2021Credential+setCredentialStatus) ⇒ [StatusList2021Entry](#StatusList2021Entry) + * [.purpose()](#StatusList2021Credential+purpose) ⇒ [StatusPurpose](#StatusPurpose) + * [.entry(index)](#StatusList2021Credential+entry) ⇒ [CredentialStatus](#CredentialStatus) + * [.clone()](#StatusList2021Credential+clone) ⇒ [StatusList2021Credential](#StatusList2021Credential) + * [.toJSON()](#StatusList2021Credential+toJSON) ⇒ any + * _static_ + * [.fromJSON(json)](#StatusList2021Credential.fromJSON) ⇒ [StatusList2021Credential](#StatusList2021Credential) + + + +### new StatusList2021Credential(credential) +Creates a new [StatusList2021Credential](#StatusList2021Credential). + + +| Param | Type | +| --- | --- | +| credential | [Credential](#Credential) | + + + +### statusList2021Credential.id() ⇒ string +**Kind**: instance method of [StatusList2021Credential](#StatusList2021Credential) + + +### statusList2021Credential.setCredentialStatus(credential, index, revoked_or_suspended) ⇒ [StatusList2021Entry](#StatusList2021Entry) +Sets the given credential's status using the `index`-th entry of this status list. +Returns the created `credentialStatus`. + +**Kind**: instance method of [StatusList2021Credential](#StatusList2021Credential) + +| Param | Type | +| --- | --- | +| credential | [Credential](#Credential) | +| index | number | +| revoked_or_suspended | boolean | + + + +### statusList2021Credential.purpose() ⇒ [StatusPurpose](#StatusPurpose) +Returns the [StatusPurpose](#StatusPurpose) of this [StatusList2021Credential](#StatusList2021Credential). + +**Kind**: instance method of [StatusList2021Credential](#StatusList2021Credential) + + +### statusList2021Credential.entry(index) ⇒ [CredentialStatus](#CredentialStatus) +Returns the state of the `index`-th entry, if any. + +**Kind**: instance method of [StatusList2021Credential](#StatusList2021Credential) + +| Param | Type | +| --- | --- | +| index | number | + + + +### statusList2021Credential.clone() ⇒ [StatusList2021Credential](#StatusList2021Credential) +**Kind**: instance method of [StatusList2021Credential](#StatusList2021Credential) + + +### statusList2021Credential.toJSON() ⇒ any +**Kind**: instance method of [StatusList2021Credential](#StatusList2021Credential) + + +### StatusList2021Credential.fromJSON(json) ⇒ [StatusList2021Credential](#StatusList2021Credential) +**Kind**: static method of [StatusList2021Credential](#StatusList2021Credential) + +| Param | Type | +| --- | --- | +| json | any | + + + +## StatusList2021CredentialBuilder +Builder type to construct valid [StatusList2021Credential](#StatusList2021Credential) istances. + +**Kind**: global class + +* [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) + * [new StatusList2021CredentialBuilder([status_list])](#new_StatusList2021CredentialBuilder_new) + * [.purpose(purpose)](#StatusList2021CredentialBuilder+purpose) ⇒ [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) + * [.subjectId(id)](#StatusList2021CredentialBuilder+subjectId) ⇒ [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) + * [.expirationDate(time)](#StatusList2021CredentialBuilder+expirationDate) ⇒ [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) + * [.issuer(issuer)](#StatusList2021CredentialBuilder+issuer) ⇒ [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) + * [.context(context)](#StatusList2021CredentialBuilder+context) ⇒ [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) + * [.type(t)](#StatusList2021CredentialBuilder+type) ⇒ [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) + * [.proof(proof)](#StatusList2021CredentialBuilder+proof) ⇒ [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) + * [.build()](#StatusList2021CredentialBuilder+build) ⇒ [StatusList2021Credential](#StatusList2021Credential) + + + +### new StatusList2021CredentialBuilder([status_list]) +Creates a new [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder). + + +| Param | Type | +| --- | --- | +| [status_list] | [StatusList2021](#StatusList2021) \| undefined | + + + +### statusList2021CredentialBuilder.purpose(purpose) ⇒ [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) +Sets the purpose of the [StatusList2021Credential](#StatusList2021Credential) that is being created. + +**Kind**: instance method of [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) + +| Param | Type | +| --- | --- | +| purpose | [StatusPurpose](#StatusPurpose) | + + + +### statusList2021CredentialBuilder.subjectId(id) ⇒ [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) +Sets `credentialSubject.id`. + +**Kind**: instance method of [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) + +| Param | Type | +| --- | --- | +| id | string | + + + +### statusList2021CredentialBuilder.expirationDate(time) ⇒ [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) +Sets the expiration date of the credential. + +**Kind**: instance method of [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) + +| Param | Type | +| --- | --- | +| time | [Timestamp](#Timestamp) | + + + +### statusList2021CredentialBuilder.issuer(issuer) ⇒ [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) +Sets the issuer of the credential. + +**Kind**: instance method of [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) + +| Param | Type | +| --- | --- | +| issuer | string | + + + +### statusList2021CredentialBuilder.context(context) ⇒ [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) +Sets the context of the credential. + +**Kind**: instance method of [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) + +| Param | Type | +| --- | --- | +| context | string | + + + +### statusList2021CredentialBuilder.type(t) ⇒ [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) +Adds a credential type. + +**Kind**: instance method of [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) + +| Param | Type | +| --- | --- | +| t | string | + + + +### statusList2021CredentialBuilder.proof(proof) ⇒ [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) +Adds a credential's proof. + +**Kind**: instance method of [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) + +| Param | Type | +| --- | --- | +| proof | [Proof](#Proof) | + + + +### statusList2021CredentialBuilder.build() ⇒ [StatusList2021Credential](#StatusList2021Credential) +Attempts to build a valid [StatusList2021Credential](#StatusList2021Credential) with the previously provided data. + +**Kind**: instance method of [StatusList2021CredentialBuilder](#StatusList2021CredentialBuilder) + + +## StatusList2021Entry +[StatusList2021Entry](https://www.w3.org/TR/2023/WD-vc-status-list-20230427/#statuslist2021entry) implementation. + +**Kind**: global class + +* [StatusList2021Entry](#StatusList2021Entry) + * [new StatusList2021Entry(status_list, purpose, index, [id])](#new_StatusList2021Entry_new) + * _instance_ + * [.id()](#StatusList2021Entry+id) ⇒ string + * [.purpose()](#StatusList2021Entry+purpose) ⇒ [StatusPurpose](#StatusPurpose) + * [.index()](#StatusList2021Entry+index) ⇒ number + * [.statusListCredential()](#StatusList2021Entry+statusListCredential) ⇒ string + * [.toStatus()](#StatusList2021Entry+toStatus) ⇒ Status + * [.clone()](#StatusList2021Entry+clone) ⇒ [StatusList2021Entry](#StatusList2021Entry) + * [.toJSON()](#StatusList2021Entry+toJSON) ⇒ any + * _static_ + * [.fromJSON(json)](#StatusList2021Entry.fromJSON) ⇒ [StatusList2021Entry](#StatusList2021Entry) + + + +### new StatusList2021Entry(status_list, purpose, index, [id]) +Creates a new [StatusList2021Entry](#StatusList2021Entry). + + +| Param | Type | +| --- | --- | +| status_list | string | +| purpose | [StatusPurpose](#StatusPurpose) | +| index | number | +| [id] | string \| undefined | + + + +### statusList2021Entry.id() ⇒ string +Returns this `credentialStatus`'s `id`. + +**Kind**: instance method of [StatusList2021Entry](#StatusList2021Entry) + + +### statusList2021Entry.purpose() ⇒ [StatusPurpose](#StatusPurpose) +Returns the purpose of this entry. + +**Kind**: instance method of [StatusList2021Entry](#StatusList2021Entry) + + +### statusList2021Entry.index() ⇒ number +Returns the index of this entry. + +**Kind**: instance method of [StatusList2021Entry](#StatusList2021Entry) + + +### statusList2021Entry.statusListCredential() ⇒ string +Returns the referenced [StatusList2021Credential](#StatusList2021Credential)'s url. + +**Kind**: instance method of [StatusList2021Entry](#StatusList2021Entry) + + +### statusList2021Entry.toStatus() ⇒ Status +Downcasts [this](this) to [Status](Status) + +**Kind**: instance method of [StatusList2021Entry](#StatusList2021Entry) + + +### statusList2021Entry.clone() ⇒ [StatusList2021Entry](#StatusList2021Entry) +Deep clones the object. + +**Kind**: instance method of [StatusList2021Entry](#StatusList2021Entry) + + +### statusList2021Entry.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [StatusList2021Entry](#StatusList2021Entry) + + +### StatusList2021Entry.fromJSON(json) ⇒ [StatusList2021Entry](#StatusList2021Entry) +Deserializes an instance from a JSON object. + +**Kind**: static method of [StatusList2021Entry](#StatusList2021Entry) + +| Param | Type | +| --- | --- | +| json | any | + + + +## Storage +A type wrapping a `JwkStorage` and `KeyIdStorage` that should always be used together when +working with storage backed DID documents. + +**Kind**: global class + +* [Storage](#Storage) + * [new Storage(jwkStorage, keyIdStorage)](#new_Storage_new) + * [.keyIdStorage()](#Storage+keyIdStorage) ⇒ KeyIdStorage + * [.keyStorage()](#Storage+keyStorage) ⇒ JwkStorage + + + +### new Storage(jwkStorage, keyIdStorage) +Constructs a new `Storage`. + + +| Param | Type | +| --- | --- | +| jwkStorage | JwkStorage | +| keyIdStorage | KeyIdStorage | + + + +### storage.keyIdStorage() ⇒ KeyIdStorage +Obtain the wrapped `KeyIdStorage`. + +**Kind**: instance method of [Storage](#Storage) + + +### storage.keyStorage() ⇒ JwkStorage +Obtain the wrapped `JwkStorage`. + +**Kind**: instance method of [Storage](#Storage) + + +## Timestamp +**Kind**: global class + +* [Timestamp](#Timestamp) + * [new Timestamp()](#new_Timestamp_new) + * _instance_ + * [.toRFC3339()](#Timestamp+toRFC3339) ⇒ string + * [.checkedAdd(duration)](#Timestamp+checkedAdd) ⇒ [Timestamp](#Timestamp) \| undefined + * [.checkedSub(duration)](#Timestamp+checkedSub) ⇒ [Timestamp](#Timestamp) \| undefined + * [.toJSON()](#Timestamp+toJSON) ⇒ any + * _static_ + * [.parse(input)](#Timestamp.parse) ⇒ [Timestamp](#Timestamp) + * [.nowUTC()](#Timestamp.nowUTC) ⇒ [Timestamp](#Timestamp) + * [.fromJSON(json)](#Timestamp.fromJSON) ⇒ [Timestamp](#Timestamp) + + + +### new Timestamp() +Creates a new [Timestamp](#Timestamp) with the current date and time. + + + +### timestamp.toRFC3339() ⇒ string +Returns the [Timestamp](#Timestamp) as an RFC 3339 `String`. + +**Kind**: instance method of [Timestamp](#Timestamp) + + +### timestamp.checkedAdd(duration) ⇒ [Timestamp](#Timestamp) \| undefined +Computes `self + duration` + +Returns `null` if the operation leads to a timestamp not in the valid range for [RFC 3339](https://tools.ietf.org/html/rfc3339). + +**Kind**: instance method of [Timestamp](#Timestamp) + +| Param | Type | +| --- | --- | +| duration | [Duration](#Duration) | + + + +### timestamp.checkedSub(duration) ⇒ [Timestamp](#Timestamp) \| undefined +Computes `self - duration` + +Returns `null` if the operation leads to a timestamp not in the valid range for [RFC 3339](https://tools.ietf.org/html/rfc3339). + +**Kind**: instance method of [Timestamp](#Timestamp) + +| Param | Type | +| --- | --- | +| duration | [Duration](#Duration) | + + + +### timestamp.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [Timestamp](#Timestamp) + + +### Timestamp.parse(input) ⇒ [Timestamp](#Timestamp) +Parses a [Timestamp](#Timestamp) from the provided input string. + +**Kind**: static method of [Timestamp](#Timestamp) + +| Param | Type | +| --- | --- | +| input | string | + + + +### Timestamp.nowUTC() ⇒ [Timestamp](#Timestamp) +Creates a new [Timestamp](#Timestamp) with the current date and time. + +**Kind**: static method of [Timestamp](#Timestamp) + + +### Timestamp.fromJSON(json) ⇒ [Timestamp](#Timestamp) +Deserializes an instance from a JSON object. + +**Kind**: static method of [Timestamp](#Timestamp) + +| Param | Type | +| --- | --- | +| json | any | + + + +## UnknownCredential +**Kind**: global class + +* [UnknownCredential](#UnknownCredential) + * _instance_ + * [.tryIntoJwt()](#UnknownCredential+tryIntoJwt) ⇒ [Jwt](#Jwt) \| undefined + * [.tryIntoCredential()](#UnknownCredential+tryIntoCredential) ⇒ [Credential](#Credential) \| undefined + * [.tryIntoRaw()](#UnknownCredential+tryIntoRaw) ⇒ Record.<string, any> \| undefined + * [.toJSON()](#UnknownCredential+toJSON) ⇒ any + * [.clone()](#UnknownCredential+clone) ⇒ [UnknownCredential](#UnknownCredential) + * _static_ + * [.fromJSON(json)](#UnknownCredential.fromJSON) ⇒ [UnknownCredential](#UnknownCredential) + + + +### unknownCredential.tryIntoJwt() ⇒ [Jwt](#Jwt) \| undefined +Returns a [Jwt](#Jwt) if the credential is of type string, `undefined` otherwise. + +**Kind**: instance method of [UnknownCredential](#UnknownCredential) + + +### unknownCredential.tryIntoCredential() ⇒ [Credential](#Credential) \| undefined +Returns a [Credential](#Credential) if the credential is of said type, `undefined` otherwise. + +**Kind**: instance method of [UnknownCredential](#UnknownCredential) + + +### unknownCredential.tryIntoRaw() ⇒ Record.<string, any> \| undefined +Returns the contained value as an Object, if it can be converted, `undefined` otherwise. + +**Kind**: instance method of [UnknownCredential](#UnknownCredential) + + +### unknownCredential.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [UnknownCredential](#UnknownCredential) + + +### unknownCredential.clone() ⇒ [UnknownCredential](#UnknownCredential) +Deep clones the object. + +**Kind**: instance method of [UnknownCredential](#UnknownCredential) + + +### UnknownCredential.fromJSON(json) ⇒ [UnknownCredential](#UnknownCredential) +Deserializes an instance from a JSON object. + +**Kind**: static method of [UnknownCredential](#UnknownCredential) + +| Param | Type | +| --- | --- | +| json | any | + + + +## VerificationMethod +A DID Document Verification Method. + +**Kind**: global class + +* [VerificationMethod](#VerificationMethod) + * [new VerificationMethod(id, controller, type_, data)](#new_VerificationMethod_new) + * _instance_ + * [.id()](#VerificationMethod+id) ⇒ [DIDUrl](#DIDUrl) + * [.setId(id)](#VerificationMethod+setId) + * [.controller()](#VerificationMethod+controller) ⇒ [CoreDID](#CoreDID) + * [.setController(did)](#VerificationMethod+setController) + * [.type()](#VerificationMethod+type) ⇒ [MethodType](#MethodType) + * [.setType(type_)](#VerificationMethod+setType) + * [.data()](#VerificationMethod+data) ⇒ [MethodData](#MethodData) + * [.setData(data)](#VerificationMethod+setData) + * [.properties()](#VerificationMethod+properties) ⇒ Map.<string, any> + * [.setPropertyUnchecked(key, value)](#VerificationMethod+setPropertyUnchecked) + * [.toJSON()](#VerificationMethod+toJSON) ⇒ any + * [.clone()](#VerificationMethod+clone) ⇒ [VerificationMethod](#VerificationMethod) + * _static_ + * [.newFromJwk(did, key, [fragment])](#VerificationMethod.newFromJwk) ⇒ [VerificationMethod](#VerificationMethod) + * [.fromJSON(json)](#VerificationMethod.fromJSON) ⇒ [VerificationMethod](#VerificationMethod) + + + +### new VerificationMethod(id, controller, type_, data) +Create a custom [VerificationMethod](#VerificationMethod). + + +| Param | Type | +| --- | --- | +| id | [DIDUrl](#DIDUrl) | +| controller | [CoreDID](#CoreDID) | +| type_ | [MethodType](#MethodType) | +| data | [MethodData](#MethodData) | + + + +### verificationMethod.id() ⇒ [DIDUrl](#DIDUrl) +Returns a copy of the [DIDUrl](#DIDUrl) of the [VerificationMethod](#VerificationMethod)'s `id`. + +**Kind**: instance method of [VerificationMethod](#VerificationMethod) + + +### verificationMethod.setId(id) +Sets the id of the [VerificationMethod](#VerificationMethod). + +**Kind**: instance method of [VerificationMethod](#VerificationMethod) + +| Param | Type | +| --- | --- | +| id | [DIDUrl](#DIDUrl) | + + + +### verificationMethod.controller() ⇒ [CoreDID](#CoreDID) +Returns a copy of the `controller` `DID` of the [VerificationMethod](#VerificationMethod). + +**Kind**: instance method of [VerificationMethod](#VerificationMethod) + + +### verificationMethod.setController(did) +Sets the `controller` `DID` of the [VerificationMethod](#VerificationMethod) object. + +**Kind**: instance method of [VerificationMethod](#VerificationMethod) + +| Param | Type | +| --- | --- | +| did | [CoreDID](#CoreDID) | + + + +### verificationMethod.type() ⇒ [MethodType](#MethodType) +Returns a copy of the [VerificationMethod](#VerificationMethod) type. + +**Kind**: instance method of [VerificationMethod](#VerificationMethod) + + +### verificationMethod.setType(type_) +Sets the [VerificationMethod](#VerificationMethod) type. + +**Kind**: instance method of [VerificationMethod](#VerificationMethod) + +| Param | Type | +| --- | --- | +| type_ | [MethodType](#MethodType) | + + + +### verificationMethod.data() ⇒ [MethodData](#MethodData) +Returns a copy of the [VerificationMethod](#VerificationMethod) public key data. + +**Kind**: instance method of [VerificationMethod](#VerificationMethod) + + +### verificationMethod.setData(data) +Sets [VerificationMethod](#VerificationMethod) public key data. + +**Kind**: instance method of [VerificationMethod](#VerificationMethod) + +| Param | Type | +| --- | --- | +| data | [MethodData](#MethodData) | + + + +### verificationMethod.properties() ⇒ Map.<string, any> +Get custom properties of the Verification Method. + +**Kind**: instance method of [VerificationMethod](#VerificationMethod) + + +### verificationMethod.setPropertyUnchecked(key, value) +Adds a custom property to the Verification Method. +If the value is set to `null`, the custom property will be removed. + +### WARNING +This method can overwrite existing properties like `id` and result +in an invalid Verification Method. + +**Kind**: instance method of [VerificationMethod](#VerificationMethod) + +| Param | Type | +| --- | --- | +| key | string | +| value | any | + + + +### verificationMethod.toJSON() ⇒ any +Serializes this to a JSON object. + +**Kind**: instance method of [VerificationMethod](#VerificationMethod) + + +### verificationMethod.clone() ⇒ [VerificationMethod](#VerificationMethod) +Deep clones the object. + +**Kind**: instance method of [VerificationMethod](#VerificationMethod) + + +### VerificationMethod.newFromJwk(did, key, [fragment]) ⇒ [VerificationMethod](#VerificationMethod) +Creates a new [VerificationMethod](#VerificationMethod) from the given `did` and [Jwk](#Jwk). If `fragment` is not given +the `kid` value of the given `key` will be used, if present, otherwise an error is returned. + +### Recommendations +The following recommendations are essentially taken from the `publicKeyJwk` description from the [DID specification](https://www.w3.org/TR/did-core/#dfn-publickeyjwk): +- It is recommended that verification methods that use `Jwks` to represent their public keys use the value of + `kid` as their fragment identifier. This is +done automatically if `None` is passed in as the fragment. +- It is recommended that [Jwk](#Jwk) kid values are set to the public key fingerprint. + +**Kind**: static method of [VerificationMethod](#VerificationMethod) + +| Param | Type | +| --- | --- | +| did | [CoreDID](#CoreDID) \| IToCoreDID | +| key | [Jwk](#Jwk) | +| [fragment] | string \| undefined | + + + +### VerificationMethod.fromJSON(json) ⇒ [VerificationMethod](#VerificationMethod) +Deserializes an instance from a JSON object. + +**Kind**: static method of [VerificationMethod](#VerificationMethod) + +| Param | Type | +| --- | --- | +| json | any | + + + +## StatusCheck +Controls validation behaviour when checking whether or not a credential has been revoked by its +[`credentialStatus`](https://www.w3.org/TR/vc-data-model/#status). + +**Kind**: global variable + + +## Strict +Validate the status if supported, reject any unsupported +[`credentialStatus`](https://www.w3.org/TR/vc-data-model/#status) types. + +Only `RevocationBitmap2022` is currently supported. + +This is the default. + +**Kind**: global variable + + +## SkipUnsupported +Validate the status if supported, skip any unsupported +[`credentialStatus`](https://www.w3.org/TR/vc-data-model/#status) types. + +**Kind**: global variable + + +## SkipAll +Skip all status checks. + +**Kind**: global variable + + +## CredentialStatus +**Kind**: global variable + + +## PayloadType +**Kind**: global variable + + +## ProofAlgorithm +**Kind**: global variable + + +## StatusPurpose +Purpose of a [StatusList2021](#StatusList2021). + +**Kind**: global variable + + +## FailFast +Declares when validation should return if an error occurs. + +**Kind**: global variable + + +## AllErrors +Return all errors that occur during validation. + +**Kind**: global variable + + +## FirstError +Return after the first error occurs. + +**Kind**: global variable + + +## StateMetadataEncoding +**Kind**: global variable + + +## SerializationType +**Kind**: global variable + + +## MethodRelationship +**Kind**: global variable + + +## PresentationProofAlgorithm +**Kind**: global variable + + +## SubjectHolderRelationship +Declares how credential subjects must relate to the presentation holder. + +See also the [Subject-Holder Relationship](https://www.w3.org/TR/vc-data-model/#subject-holder-relationships) section of the specification. + +**Kind**: global variable + + +## AlwaysSubject +The holder must always match the subject on all credentials, regardless of their [`nonTransferable`](https://www.w3.org/TR/vc-data-model/#nontransferable-property) property. +This variant is the default. + +**Kind**: global variable + + +## SubjectOnNonTransferable +The holder must match the subject only for credentials where the [`nonTransferable`](https://www.w3.org/TR/vc-data-model/#nontransferable-property) property is `true`. + +**Kind**: global variable + + +## Any +The holder is not required to have any kind of relationship to any credential subject. + +**Kind**: global variable + + +## encodeB64(data) ⇒ string +Encode the given bytes in url-safe base64. + +**Kind**: global function + +| Param | Type | +| --- | --- | +| data | Uint8Array | + + + +## decodeB64(data) ⇒ Uint8Array +Decode the given url-safe base64-encoded slice into its raw bytes. + +**Kind**: global function + +| Param | Type | +| --- | --- | +| data | Uint8Array | + + + +## start() +Initializes the console error panic hook for better error messages + +**Kind**: global function + + +## verifyEd25519(alg, signingInput, decodedSignature, publicKey) +Verify a JWS signature secured with the `EdDSA` algorithm and curve `Ed25519`. + +This function is useful when one is composing a `IJwsVerifier` that delegates +`EdDSA` verification with curve `Ed25519` to this function. + +# Warning + +This function does not check whether `alg = EdDSA` in the protected header. Callers are expected to assert this +prior to calling the function. + +**Kind**: global function + +| Param | Type | +| --- | --- | +| alg | JwsAlgorithm | +| signingInput | Uint8Array | +| decodedSignature | Uint8Array | +| publicKey | [Jwk](#Jwk) | + diff --git a/docs/content/sidebars/developer.js b/docs/content/sidebars/developer.js index ed9cad4a187..0454de9be14 100644 --- a/docs/content/sidebars/developer.js +++ b/docs/content/sidebars/developer.js @@ -771,6 +771,79 @@ const developer = [ }, ], }, + { + type: 'category', + label: 'IOTA Identity', + link: { + type: 'doc', + id: 'guides/developer/iota-identity/welcome', + }, + items: [ + { + type: 'doc', + id: 'guides/developer/iota-identity/welcome', + label: 'Welcome', + }, + { + type: 'category', + label: 'Getting Started', + collapsed: false, + items: ['guides/developer/iota-identity/getting-started/rust', 'guides/developer/iota-identity/getting-started/wasm'], + }, + { + type: 'category', + label: 'Explanations', + items: [ + 'guides/developer/iota-identity/explanations/decentralized-identifiers', + 'guides/developer/iota-identity/explanations/verifiable-credentials', + 'guides/developer/iota-identity/explanations/verifiable-presentations', + 'guides/developer/iota-identity/explanations/about-alias-outputs', + ], + }, + { + type: 'category', + label: 'How To', + items: [ + { + type: 'category', + label: 'Decentralized Identifiers (DID)', + items: [ + 'guides/developer/iota-identity/how-tos/decentralized-identifiers/create', + 'guides/developer/iota-identity/how-tos/decentralized-identifiers/update', + 'guides/developer/iota-identity/how-tos/decentralized-identifiers/resolve', + 'guides/developer/iota-identity/how-tos/decentralized-identifiers/delete', + ], + }, + { + type: 'category', + label: 'Verifiable Credentials', + items: [ + 'guides/developer/iota-identity/how-tos/verifiable-credentials/create', + 'guides/developer/iota-identity/how-tos/verifiable-credentials/revocation', + 'guides/developer/iota-identity/how-tos/verifiable-credentials/selective-disclosure', + 'guides/developer/iota-identity/how-tos/verifiable-credentials/zero-knowledge-selective-disclosure', + ], + }, + { + type: 'category', + label: 'Verifiable Presentations', + items: ['guides/developer/iota-identity/how-tos/verifiable-presentations/create-and-validate'], + }, + { + type: 'category', + label: 'Domain Linkage', + items: ['guides/developer/iota-identity/how-tos/domain-linkage/create-and-verify'], + }, + 'guides/developer/iota-identity/how-tos/key-storage', + ], + }, + 'guides/developer/iota-identity/glossary', + 'guides/developer/iota-identity/contribute', + 'guides/developer/iota-identity/workflow', + 'guides/developer/iota-identity/contact', + 'guides/developer/iota-identity/faq', + ], + }, { type: 'category', label: 'Integrate Your Exchange', diff --git a/docs/content/sidebars/references.js b/docs/content/sidebars/references.js index 4f36df8c3ba..bed31f0a772 100644 --- a/docs/content/sidebars/references.js +++ b/docs/content/sidebars/references.js @@ -305,6 +305,30 @@ const references = [ }, ], }, + { + type: 'category', + label: 'IOTA Identity', + link: { + type: 'doc', + id: 'standards/iota-identity/overview', + }, + items: [ + 'standards/iota-identity/overview', + 'standards/iota-identity/iota-did-method-spec', + 'standards/iota-identity/revocation-bitmap-2022', + 'standards/iota-identity/revocation-timeframe-2024', + { + type: 'doc', + id: 'references/iota-identity/wasm', + label: 'Wasm', + }, + { + type: 'link', + label: 'Rust', + href: 'https://docs.rs/identity_iota/latest/identity_iota/index.html', + }, + ], + }, 'references/iota-glossary', { type: 'category', diff --git a/docs/content/standards/iota-identity/iota-did-method-spec.mdx b/docs/content/standards/iota-identity/iota-did-method-spec.mdx new file mode 100644 index 00000000000..1535df5b913 --- /dev/null +++ b/docs/content/standards/iota-identity/iota-did-method-spec.mdx @@ -0,0 +1,263 @@ +--- +title: IOTA DID Method Specification v1.0 +sidebar_label: DID Method +description: How IOTA Identity implements the Decentralized Identifiers Standard on the IOTA Tangle. +image: /img/Identity_icon.png +tags: + - DID + - specs + - specifications + - Decentralized Identifiers + - Tangle + - format +--- + +# IOTA DID Method Specification v1.0 + +2023-08-23 + +## Abstract + +The IOTA DID Method Specification describes a method of implementing the [Decentralized Identifiers](https://www.w3.org/TR/did-core/) (DID) standard on [IOTA](https://iota.org), a Distributed Ledger Technology (DLT). It conforms to the [DID specification v1.0](https://www.w3.org/TR/did-core/) and describes how to perform Create, Read, Update and Delete (CRUD) operations for IOTA DID Documents using unspent transaction outputs (_UTXO_) on the IOTA and [Shimmer](https://shimmer.network/) networks, introduced with the [Stardust upgrade](https://blog.shimmer.network/stardust-upgrade-in-a-nutshell/). + +## Data Types & Subschema Notation + +Data types and subschemas used throughout this TIP are defined in [TIP-21](https://github.com/iotaledger/tips/blob/v1.2.0/tips/TIP-0021/tip-0021.md). + +## Introduction + +### UTXO Ledger + +The unspent transaction output ([UTXO](/tips/tips/TIP-0020/)) model defines a ledger state which is comprised of unspent outputs. Outputs are created by a transaction consuming outputs of previous transactions as inputs. The Stardust version of the protocol defines several output types, the relevant ones for the IOTA DID Method are: Basic Outputs for _value transactions_, and Alias Outputs for storage of DID Documents. + +All outputs must hold a minimum amount of tokens to be stored on the ledger. For output types that can hold arbitrary data, for instance the Alias Output, the amount of tokens held by the output must cover the byte cost of the data stored. This prevents the ledger size from growing uncontrollably while guaranteeing that the data is not pruned from the nodes, which is important for resolving DID Documents. This deposit is fully refundable and can be reclaimed when the output is destroyed. + +Data stored in an output and covered by the storage deposit will be stored in _all_ nodes on the network and can be retrieved from any node. This provides strong guarantees for any data stored in the ledger. + +### Alias Output + +The [Alias Output](https://github.com/iotaledger/tips/blob/v1.2.0/tips/TIP-0018/tip-0018.md#alias-output) is a specific implementation of the [UTXO state machine](https://github.com/iotaledger/tips/blob/v1.2.0/tips/TIP-0018/tip-0018.md#chain-constraint-in-utxo). Some of its relevant properties are: + +- **Amount**: the amount of IOTA coins held by the output. +- **Alias ID**: 32 byte array, a unique identifier of the alias, which is the BLAKE2b-256 hash + of the Output ID that created it. +- **State Index**: A counter that must increase by 1 every time the alias is state transitioned. +- **State Metadata**: Dynamically sized array of arbitrary bytes with a length up to `Max Metadata Length`, as defined in [TIP-22](https://github.com/iotaledger/tips/blob/v1.2.0/tips/TIP-0022/tip-0022.md). Can only be changed by the state controller. +- **Unlock Conditions**: + - State Controller Address Unlock Condition + - Governor Address Unlock Condition + +Consuming an Alias Output in a transaction may transition it into the next state. The current state is defined as the consumed Alias Output, while the next state is defined as the **Alias Output with the same explicit `Alias ID` on the output side**. There are two types of transitions: `state transition` and `governance transition`. + +All outputs include an `Unlock Conditions` property. This feature defines how the output can be unlocked and spent. The Alias Output supports two types of unlock conditions that can be set: the state controller and governor. Each of these can be either an Ed25519 Address, Alias Address or an NFT Address. An Alias Output can have at most one of each unlock condition. + +The state controller can unlock a state transition. It is identified by an incremented `State Index` and can change the fields `Amount`, `State Index`, `State Metadata` among other properties. + +The governor, on the other hand, can unlock a governance transition indicated by an unchanged `State Index`. A governance transition can change the addresses of the state controller and governor. It also allows destroying the Alias Output. + +### Ledger and DID + +Storing DID Documents in the ledger state means they inherently benefit from the guarantees the ledger provides. + +1. Conflicts among nodes are resolved and dealt with by the ledger. +2. Replay attacks are mitigated since transactions need to be confirmed by the ledger. +3. Through the `State Index` a linear history for updates of a DID Document is provided. + +## DID Method Name + +The `method-name` to identify this DID method is: `iota`. + +A DID that uses this method MUST begin with the following prefix: `did:iota`. Following the generic DID specification, this string MUST be lowercase. + +## DID Format + +The DIDs that follow this method have the following ABNF syntax. It uses the syntax in [RFC5234](https://www.rfc-editor.org/rfc/rfc5234) and the corresponding definition for `digit`. + +``` +iota-did = "did:iota:" iota-specific-idstring +iota-specific-idstring = [ iota-network ":" ] iota-tag +iota-network = 1*6network-char +iota-tag = "0x" 64lowercase-hex +lowercase-hex = digit / "a" / "b" / "c" / "d" / "e" / "f" +network-char = %x61-7A / digit ; corresponds to the character range from "a" to "z" and "0" to "9". +``` + +It starts with the string "did:iota:", followed by an optional network name (1 to 6 lowercase alpha characters) and a colon, then the tag. +The tag starts with "0x" followed by a hex-encoded `Alias ID` with lower case a-f. + +### IOTA-Network + +The iota-network is an identifier of the network where the DID is stored. This network must be an IOTA Ledger, but can either be a public or private network, permissionless or permissioned. + +The following values are reserved and cannot reference other networks: + +1. `iota` references the main network which refers to the ledger known to host the IOTA cryptocurrency. +2. `atoi` references the development network of IOTA. +3. `smr` references the shimmer network. +4. `rms` references the development network of Shimmer. + +When no IOTA network is specified, it is assumed that the DID is located on the `iota` network. This means that the following DIDs will resolve to the same DID Document: + +``` +did:iota:iota:0xe4edef97da1257e83cbeb49159cfdd2da6ac971ac447f233f8439cf29376ebfe +did:iota:0xe4edef97da1257e83cbeb49159cfdd2da6ac971ac447f233f8439cf29376ebfe +``` + +### IOTA-Tag + +An IOTA-tag is a hex-encoded `Alias ID`. The `Alias ID` itself is a unique identifier of the alias, which is the BLAKE2b-256 hash of the Output ID that created it. +This tag identifies the Alias Output where the DID Document is stored, and it will not be known before the generation of the DID since it will be assigned when the Alias Output is created. + +### Anatomy of the State Metadata + +In the `State Metadata` of the Alias Output must be a byte packed payload with header fields as follows: + +| Name | Type | Description | +| ------------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Document Type | ByteArray[3] | Set to value **DID** to denote a DID Document. | +| Version | uint8 | Set value **1** to denote the version number of this method | +| Encoding | uint8 | Set to value to **0** to denote JSON encoding without compression. | +| Payload | (uint16)ByteArray | A DID Document and its metadata, where every occurrence of the DID in the document is replaced by `did:0:0`. It must be encoded according to `Encoding`. | + +The types are defined in [TIP-21](/tips/tips/TIP-0021/#data-types). + +#### Payload + +The payload must contain the following fields: + +- `meta`: contains metadata about the DID Document. For example, `created` to indicate the time of + creation, and `updated` to indicate the time of the last update to the document. It may also include other properties. +- `doc`: contains the DID Document. In the example below, the document only contains one verification method. The `id` and `controller` is specified by `did:0:0` which references the DID of the document itself, since the DID is unknown at the time of publishing. It also deduplicates the DID of the document to reduce the size of the state metadata, in turn reducing the required storage deposit. + +Example State Metadata Document: + +```json +{ + "doc": { + "id": "did:0:0", + "verificationMethod": [ + { + "id": "did:0:0#jkGOGVO3Te7ADpvlplr47eP9ucLt41zm", + "controller": "did:0:0", + "type": "JsonWebKey", + "publicKeyJwk": { + "kty": "OKP", + "alg": "EdDSA", + "kid": "jkGOGVO3Te7ADpvlplr47eP9ucLt41zm", + "crv": "Ed25519", + "x": "D5w8vG6tKEnpBAia5J4vNgLID8k0BspHz-cVMBCC3RQ" + } + } + ], + "authentication": ["did:0:0#jkGOGVO3Te7ADpvlplr47eP9ucLt41zm"] + }, + "meta": { + "created": "2023-08-28T14:49:37Z", + "updated": "2023-08-28T14:50:27Z" + } +} +``` + +## Controllers + +A state controller can directly update the DID Document and the amount of tokens held by the Alias Output, but it cannot destroy the output. A governor, on the other hand, can indirectly update the DID Document by updating the state controller. The governor can also destroy the output by performing a governance transition without producing an Alias Output with the same `Alias ID`. + +As of now, only one state controller and one governor can be set for an Alias Output. Support for multiple controllers may be possible depending on future updates of the protocol. + +## CRUD Operations + +Create, Read, Update and Delete (CRUD) operations that change the DID Documents are done through state or governance transitions of the Alias Output. + +**These operations require fund transfer to cover byte cost. Transactions must be carefully done in order to avoid fund loss.** For example, the amount of funds in the inputs should equal these in the outputs. Additionally, private keys of controllers must be stored securely. + +### Create + +In order to create a simple self controlled DID two things are required: + +1. An Ed25519 Address for which the private key is available, or control over an Alias or NFT Output. +2. A Basic, Alias or NFT Output with enough coins to cover the byte cost. + +Creation steps: + +1. Create the content of the DID Document like verification methods, services, etc. +2. Create the payload and the headers as described in the [Anatomy of the State Metadata](#anatomy-of-the-state-metadata). +3. Create a new Alias Output with the payload and the headers stored in its `State Metadata`. +4. Set the state controller and the governor unlock conditions to the addresses that should control state and governance transitions, respectively. +5. Set enough tokens in the output to cover the byte cost. +6. Publish a new transaction with an existing output that contains at least the storage deposit from step 6 as input, and the newly created Alias Output as output. + +Once the transaction is confirmed, the DID is published and can be formatted by using the `Alias ID` as the tag in [DID Format](#did-format). + +### Read + +The following steps can be used to read the latest DID Document associated with a DID. + +1. Obtain the `Alias ID` from the DID by extracting the `iota-tag` from the DID, see [DID Format](#did-format). +2. Obtain the network of the DID by extracting the `iota-network` from the DID, see [DID Format](#did-format). +3. Query the Alias Output corresponding to the `Alias ID` using a node running the [inx indexer](https://github.com/iotaledger/inx-indexer). Nodes usually include this indexer by default. +4. Assert that the extracted network matches the one returned from the node. Return an error otherwise. +5. Assert that the `Alias ID` of the returned output matches the `Alias ID` extracted from the DID. Return an error otherwise. +6. Retrieve the value of the `State Metadata` field from the returned output. +7. Validate the contents match the structure described in [Anatomy of the State Metadata](#anatomy-of-the-state-metadata). Return an error otherwise. +8. Decode the DID Document from the `State Metadata`. +9. Replace the placeholder `did:0:0` with the DID given as input. + +### Update + +Updating a DID Document can be achieved by the state controller performing a state transition of the Alias Output with the updated content: + +1. Create a copy of the Alias Output with the `Alias ID` set explicitly. +2. Pack the updated DID Document, as described in the [Anatomy of the State Metadata](#anatomy-of-the-state-metadata), into the `State Metadata` of the output. +3. Increment the `State Index`. +4. Set the `amount` of coins sufficient to cover the byte cost. +5. Publish a new transaction that includes the current Alias Output as input (along with any required Basic Outputs to consume to cover the `amount`, if increased) and the updated one as output. If the state controller unlock of the Alias Output references other Alias or NFT Outputs, those outputs must be unlocked in the same transaction, recursively. + +### Delete + +#### Deactivate + +Temporarily deactivating a DID can be done by deleting the contents of the `State Meadata` in the Alias Output, setting it to an empty byte array, and publishing an [update](#update). + +Another option is to [update](#update) the DID Document and set the `deactivated` property in its `metadata` to true. In both cases, the deactivated DID Document will be marked as `deactivated` when resolved. + +#### Destroy + +In order to permanently destroy a DID, a new transaction can be published by the governor that consumes the Alias Output without having a corresponding Alias Output on the output side with the same explicit `Alias ID`. This results in destroying the Alias Output and the DID. + +Note that this operation irreversibly and irrecoverably deletes the DID. This is because the `Alias ID` from which an IOTA DID is derived (see [IOTA-Tag](#iota-tag)) is generated from the hash of the input transaction that created it, which cannot generally be replicated. + +## IOTA Identity standards + +The `did:iota` method is implemented in the [IOTA Identity framework](https://github.com/iotaledger/identity.rs). This framework supports a number of operations that are standardized, some are standardized across the SSI community, and some are the invention of the IOTA Foundation. + +### Revocation + +Revocation of verifiable credentials and signatures can be achieved using the [Revocation Bitmap 2022](./revocation-bitmap-2022.mdx) where issuers store a bitmap of indices in the DID Document. These indices correspond to verifiable credentials they have issued. If the binary value of the index in the bitmap is 1 (one), the verifiable credential is revoked, if it is 0 (zero) it is not revoked. + +### Standardized Services + +The IOTA Identity framework also standardized certain `services` that are embedded in the DID Document. It is RECOMMENDED to implement these when implementing the `did:iota` method. + +Currently standardized `services`: + +- [Revocation Bitmap Service](./revocation-bitmap-2022.mdx#revocation-bitmap-service) + +## Security Considerations + +The `did:iota` method is implemented on the [IOTA](https://iota.org), a public permissionless and feeless Distributed Ledger Technology (DLT), making it resistant against almost all censorship attack vectors. Up until the `Coordicide` update for the IOTA network, a dependency on the coordinator exists for resolving ordering conflicts. This has a minor censorship possibility, that, in the worst case, can prevent transactions from getting confirmed. + +### Private Key Management + +All private keys or seeds used for the `did:iota` method should be equally well protected by the users. Private keys of the state controller and the governor are especially important as they control how keys are added or removed, providing full control over the identity. The IOTA Identity framework utilizes the [Stronghold project](https://github.com/iotaledger/stronghold.rs), a secure software implementation isolating digital secrets from exposure to hacks or leaks. Developers may choose to add other ways to manage the private keys in a different manner. + +## Privacy Considerations + +### Personal Identifiable Information + +The public IOTA and Shimmer networks are immutable. This means that once something is included, it can never be completely removed. For example, destroying an Alias Output will remove it from the ledger state, but it can still be stored in permanodes or by any party that records historical ledger states. + +That directly conflicts with certain privacy laws such as GDPR, which have a 'right-to-be-forgotten' for Personal Identifiable Information (PII). As such, users should NEVER upload any PII, including inside DID Documents. While verifiable credentials can be made public, this should only be utilized by Identity for Organisations and Identity for Things. + +### Correlation Risks + +As with any DID method, identities can be linked if they are used too often and their usage somehow becomes public. See [DID Correlation Risks](https://www.w3.org/TR/did-core/#did-correlation-risks). Additionally, a DID can be correlated with funds if the Alias Output used to store the DID Document or any of its controllers is used for holding, transferring or controlling coins or NFTs. diff --git a/docs/content/standards/iota-identity/overview.mdx b/docs/content/standards/iota-identity/overview.mdx new file mode 100644 index 00000000000..1ad9053c490 --- /dev/null +++ b/docs/content/standards/iota-identity/overview.mdx @@ -0,0 +1,15 @@ +--- +title: Specifications Overview +sidebar_label: Overview +description: Provide overview of the specifications +image: /img/Identity_icon.png +tags: + - specifications +--- + +While IOTA Identity implements many existing standards, it also adds some additional features we would like to standardize ourselves. This section covers these features and how they work in great detail. These are not light reads and can be skipped. + +The current specifications are: + +- [IOTA DID](iota-did-method-spec.mdx): The specification for the IOTA DID Method implemented on the _Tangle_. +- [Revocation Bitmap 2022](revocation-bitmap-2022.mdx): The specification for an on-Tangle credential revocation mechanism. diff --git a/docs/content/standards/iota-identity/revocation-bitmap-2022.mdx b/docs/content/standards/iota-identity/revocation-bitmap-2022.mdx new file mode 100644 index 00000000000..5c7b89aaa8d --- /dev/null +++ b/docs/content/standards/iota-identity/revocation-bitmap-2022.mdx @@ -0,0 +1,201 @@ +--- +title: Revocation Bitmap +sidebar_label: Revocation Bitmap +description: The specification for the embedded revocation bitmap. +image: /img/Identity_icon.png +tags: + - DID + - specs + - specifications + - revocation + - bitmap +--- + +# Revocation Bitmap 2022 + +## Abstract + +This specification describes a mechanism for publishing the revocation status of [verifiable credentials](../../explanations/verifiable-credentials.mdx) embedded in an issuer's DID document. + +## Introduction + +Revocation gives an issuer the capability to invalidate a credential they issued before its natural expiration date. To achieve this, issuers can embed an identifier in the `credentialStatus` field of a credential. Verifiers can then lookup that identifier in a separate list, to check whether the credential is still valid. This document specifies a mechanism of embedding such a list, in form of a bitmap, in the DID document of the issuer, where each bitmap index corresponds to a credential they have issued. This mechanism is space-efficient and enables a verifier to check a credential's status in a privacy-preserving manner and without requiring additional lookups or external resources. + +## Revocation Bitmap Concept + +The revocation status of a verifiable credential is expressed as a binary value. The issuer keeps a bitmap of indices corresponding to verifiable credentials they have issued. If the binary value of the index in the bitmap is 1 (one), the verifiable credential is revoked, if it is 0 (zero) it is not revoked. + +## Data Model + +### Revocation Bitmap Status + +For an issuer to enable verifiers to check the status of a verifiable credential, the [`credentialStatus`](https://www.w3.org/TR/vc-data-model/#status) property MUST be specified with the following properties: + +| Property | Description | +| :---------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `id` | The constraints on the `id` property are listed in the [Verifiable Credentials Data Model specification](https://www.w3.org/TR/vc-data-model/). The `id` MUST be a [DID URL](https://www.w3.org/TR/did-core/#did-url-syntax) that is the URL to a [Revocation Bitmap Service](#revocation-bitmap-service) in the DID Document of the issuer. It SHOULD include an `index` query set to the same value as `revocationBitmapIndex`, to uniquely identify the `credentialStatus`. If the `index` query is present, implementations SHOULD reject statuses where the `index` query's value does not match `revocationBitmapIndex`. | +| `type` | The `type` property MUST be `"RevocationBitmap2022"`. | +| `revocationBitmapIndex` | The `revocationBitmapIndex` property MUST be an unsigned, 32-bit integer expressed as a string. This is the index of the credential in the issuer's revocation bitmap. Each index SHOULD be unique among all credentials linking to the same [Revocation Bitmap Service](#revocation-bitmap-service). | + +#### Example + +An example of a verifiable credential with a `credentialStatus` of type `RevocationBitmap2022`. + +```json +{ + "@context": "https://www.w3.org/2018/credentials/v1", + "id": "https://example.edu/credentials/3732", + "type": ["VerifiableCredential", "UniversityDegreeCredential"], + "credentialSubject": { + "id": "did:iota:B8DucnzULJ9E8cmaReYoePU2b7UKE9WKxyEVov8tQA7H", + "GPA": "4.0", + "degree": "Bachelor of Science and Arts", + "name": "Alice" + }, + "issuer": "did:iota:EvaQhPXXsJsGgxSXGhZGMCvTt63KuAFtaGThx6a5nSpw", + "issuanceDate": "2022-06-13T08:04:36Z", + "credentialStatus": { + "id": "did:iota:EvaQhPXXsJsGgxSXGhZGMCvTt63KuAFtaGThx6a5nSpw?index=5#revocation", + "type": "RevocationBitmap2022", + "revocationBitmapIndex": "5" + }, + "proof": { + "type": "JcsEd25519Signature2020", + "verificationMethod": "did:iota:EvaQhPXXsJsGgxSXGhZGMCvTt63KuAFtaGThx6a5nSpw#key-1", + "signatureValue": "2eHdbDumMrer4pNVkaiYMqsVqVp2adq7bRcgTJZiw17Zeghk2ZT49YHwLwCCg35YKganBhxP6YSbzYoBK1AuCUv" + } +} +``` + +### Revocation Bitmap Service + +To allow verifiers to check the status of a [Revocation Bitmap Status](#revocation-bitmap-status), the DID document of the credential issuer MUST contain a [service](https://www.w3.org/TR/did-core/#services) with the following properties: + +| Property | Description | +| :---------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `id` | The constraints on the `id` property are listed in the [DID Core service specification](https://www.w3.org/TR/did-core/#services). The `id` property MUST be a DID URL uniquely identifying the revocation bitmap. | +| `type` | The `type` property MUST be `"RevocationBitmap2022"`. | +| `serviceEndpoint` | The `serviceEndpoint` MUST be generated according to the [service endpoint generation algorithm](#service-endpoint-generation-algorithm). | + +#### Example + +An example of an issuer's DID document where credential `"5"` in the `#revocation` service is revoked: + +```json +{ + "id": "did:iota:EvaQhPXXsJsGgxSXGhZGMCvTt63KuAFtaGThx6a5nSpw", + "verificationMethod": [ + { + "id": "did:iota:EvaQhPXXsJsGgxSXGhZGMCvTt63KuAFtaGThx6a5nSpw#key-1", + "controller": "did:iota:EvaQhPXXsJsGgxSXGhZGMCvTt63KuAFtaGThx6a5nSpw", + "type": "Ed25519VerificationKey2018", + "publicKeyMultibase": "z3hgM9fNkhwgT5mECbj1HdKoFNZgpffwQYEV8WBVHphXq" + } + ], + "capabilityInvocation": [ + { + "id": "did:iota:EvaQhPXXsJsGgxSXGhZGMCvTt63KuAFtaGThx6a5nSpw#sign-0", + "controller": "did:iota:EvaQhPXXsJsGgxSXGhZGMCvTt63KuAFtaGThx6a5nSpw", + "type": "Ed25519VerificationKey2018", + "publicKeyMultibase": "z83F6zbD3KqaxvQhqo25LvSXzoDdpZmp3EpPVonSVACwZ" + } + ], + "service": [ + { + "id": "did:iota:EvaQhPXXsJsGgxSXGhZGMCvTt63KuAFtaGThx6a5nSpw#revocation", + "type": "RevocationBitmap2022", + "serviceEndpoint": "data:application/octet-stream;base64,ZUp5ek1tQmdZR1NBQUFFZ1ptVUFBQWZPQUlF" + } + ] +} +``` + +## Algorithms + +The following algorithms define how to generate, expand and validate revocation bitmaps. + +### Service Endpoint Generation Algorithm + +The following process MUST be followed when producing a `RevocationBitmap2022` to embed in a service endpoint: + +1. Let **bitmap** be a [_roaring bitmap_](https://roaringbitmap.org/) where each bit is initialized to 0. +2. For each revoked credential with an **index** not exceeding an unsigned, 32-bit integer, set the corresponding bit in **bitmap** at **index** to 1. +3. Generate the **bitmap serialization** according to the [roaring bitmap serialization format](https://github.com/RoaringBitmap/RoaringFormatSpec/) using the **bitmap** as input. +4. Generate a **compressed bitmap** by using the ZLIB compression algorithm [[RFC 1950](https://datatracker.ietf.org/doc/html/rfc1950)] on the **bitmap serialization** and base64-encoding [[RFC4648](https://datatracker.ietf.org/doc/html/rfc4648)] the result. +5. Create the **service endpoint** by embedding the **compressed bitmap** in a data URL [[RFC2397](https://datatracker.ietf.org/doc/html/rfc2397)]. On the data url, the `` MUST be `application/octet-stream` and the `base64` attribute MUST be set. +6. Return the **service endpoint**. + +### Service Endpoint Expansion Algorithm + +The following process MUST be followed when expanding the endpoint from a service of type `RevocationBitmap2022`: + +1. Let **service endpoint** be a data url generated using the [service endpoint generation algorithm](#service-endpoint-generation-algorithm). +2. The `` of the **service endpoint** MUST be `application/octet-stream` and the `base64` attribute MUST be set, return an error otherwise. Let **compressed bitmap** be the `` part of the data url. +3. Generate an **uncompressed bitmap** by base64-decoding [[RFC4648](https://datatracker.ietf.org/doc/html/rfc4648)] the **compressed bitmap** and then decompressing the result using ZLIB [[RFC 1950](https://datatracker.ietf.org/doc/html/rfc1950)]. +4. Generate the **bitmap** by deserializing the **uncompressed bitmap** according to the [roaring bitmap serialization format](https://github.com/RoaringBitmap/RoaringFormatSpec/). +5. Return the **bitmap**. + +### Validation Algorithm + +The following steps MUST be followed when checking whether a verifiable credential is revoked: + +1. Let **credential** be a verifiable credential containing a `credentialStatus` whose `type` is `RevocationBitmap2022`. +2. Let **revocation bitmap URL** be the `id` field of the **credential**'s `credentialStatus`. +3. Resolve the **revocation bitmap URL** to a **revocation bitmap service** in the issuer's DID document, and verify that the service `type` is `RevocationBitmap2022`. Return an error otherwise. +4. Expand the endpoint of the **revocation bitmap service** into a **revocation bitmap** according to the [service endpoint expansion algorithm](#service-endpoint-expansion-algorithm). +5. Let **revocation index** be the integer value of the `revocationBitmapIndex` property contained in the `credentialStatus` of the **credential**. +6. Let **revoked** be the value of the bit at index **revocation index** in the **revocation bitmap**. +7. Return `true` if **revoked** is 1, `false` otherwise. + +## Test Vectors + +This section provides test vectors to validate implementations against. + +### Test Vector 1 + +The following data URL decodes to a bitmap of length 0 where no index is revoked: + +`"data:application/octet-stream;base64,ZUp5ek1tQUFBd0FES0FCcg=="` + +### Test Vector 2 + +The following data URL decodes to a bitmap of length 3 where indices `5`, `398`, and `67000` are revoked: + +`"data:application/octet-stream;base64,ZUp5ek1tQmdZR0lBQVVZZ1pHQ1FBR0laSUdabDZHUGN3UW9BRXVvQjlB"`. + +### Test Vector 3 + +The following data URL decodes to a bitmap of length 16384 where all indices are revoked: + +`"data:application/octet-stream;base64,ZUp6dHhERVJBQ0FNQkxESEFWS1lXZkN2Q3E0MmFESmtyMlNrM0ROckFLQ2RBQUFBQUFBQTMzbGhHZm9q"` + +## Rationale + +This section describes the rationale behind some of the design decisions of this specification. + +### Compression and maximum size + +Considering that messages published to the Tangle cannot exceed [32 KiB](https://github.com/iotaledger/tips/blob/v1.2.0/tips/TIP-0006/tip-0006.md#message-validation) in size, and that larger messages have increased requirements, the use of compression was assessed. +The precise size of a serialized bitmap varies based on the number and distribution of revoked indices. When indices are revoked uniformly randomly, roughly 100,000 - 200,000 can be achieved in a DID Document with compression, and significantly more if consecutive indices are revoked. + +ZLIB [[RFC 1950](https://datatracker.ietf.org/doc/html/rfc1950)] was chosen for having a free and open source software licence and being one of the most widely used compression schemes, which enhances the accessibility of this specification. Some other assessed algorithms produced only marginally better compression ratios but had far fewer existing implementations across different programming languages. + +### Compressed Bitstring vs. Roaring Bitmap + +Because of its space efficiency, a roaring bitmap is preferred for representing a bitmap in-memory. To avoid the dependency on roaring bitmap, we considered using a compressed bitstring as the serialization format. However, serialization of such a bitstring was 2-3x slower compared to roaring's serialization format, which becomes an issue on resource-constrained devices (e.g. smartphones) or in web browsers. + +### Comparison to `RevocationList2020` and `StatusList2021` + +The [RevocationList2020 specification](https://w3c-ccg.github.io/vc-status-rl-2020/) and [StatusList2021 specification](https://w3c-ccg.github.io/vc-status-list-2021/) both describe a similar revocation mechanism using a verifiable credential that contains a bitmap, similar to the `RevocationBitmap2022` approach. The credential is hosted outside of the DID document and the verifier thus needs to fetch it from an external resource, likely one controlled by the issuer. This has privacy implications as the issuer can track where a fetch request for the credential came from and potentially infer who the credential was verified by and for what purpose. The issuer can also potentially infer which credential was checked. Because `RevocationBitmap2022` is embedded in the issuer's DID document, which can be obtained without the their knowledge, this approach does not suffer from these privacy shortcomings. See also the [privacy considerations](#privacy-considerations). + +A downside of embedding the revocation list in the DID document is that storage in a distributed ledger (DLT) is usually more expensive than other storage hosting solutions. The DLT might also impose message size limitations, capping the total number of revocations that can be done (see also [compression](#compression)). + +Another difference is that `RevocationList2020` specifies a minimum initial size of 131,072 for its bitstring, to mitigate the potential for correlating individuals when few credentials have been issued. `RevocationBitmap2022` uses a roaring bitmap instead of a bitstring, so the maximum size is not fixed (apart from the upper bound of an unsigned 32-bit integer). This means the bitmap cannot be used to correlate small populations without more information not present in the bitmap itself. However, both schemes still reveal publicly how many credentials have been revoked, which could be used to infer other information if more knowledge about how an issuer assigns credential revocation indexes is known. + +`StatusList2021` allows for explicitly stating the purpose of the list, currently either _revocation_ or _suspension_. This specification does not mandate that revoked credentials cannot be unrevoked, which means a `RevocationBitmap2022` can effectively also be used as a suspension list. + +### Privacy Considerations + +Because the revocation bitmap is embedded in the DID document, and thus available without contacting the issuer directly, the issuer cannot correlate how a holder uses their credential. + +An observer finding a service of type `RevocationBitmap2022` in a DID document can infer that this DID belongs to an issuer. However, DIDs of issuers tend to be publicly known, in contrast to DIDs of other entities, so this is unlikely to present an issue. External observers can monitor the frequency of revocations and potentially the total number of issued credentials, depending on how the issuer assigns credential indices (e.g. starting from 0 and incrementing the index for each issued credential). diff --git a/docs/content/standards/iota-identity/revocation-timeframe-2024.mdx b/docs/content/standards/iota-identity/revocation-timeframe-2024.mdx new file mode 100644 index 00000000000..9acb71f1e00 --- /dev/null +++ b/docs/content/standards/iota-identity/revocation-timeframe-2024.mdx @@ -0,0 +1,150 @@ +--- +title: Revocation Timeframe 2024 +sidebar_label: Revocation Timeframe 2024 +description: The specification for an embeddable time-based revocation method - `RevocationTimeframe2024`. +image: /img/Identity_icon.png +tags: + - DID + - specs + - specifications + - revocation + - bitmap +--- + +# Revocation Timeframe 2024 + +## Abstract + +This specification describes a new revocation mechanism - `RevocationTimeframe2024` - that extends [`RevocationBitmap2022`](../revocation-bitmap-2022) +to address its linkability security concerns, at least when used in combination with selectively disclosable (SD-able) VCs. + +## Introduction + +`RevocationBitmap2022` allows for a simple and straightforward way for an issuer to invalidate an issued VC before its expiration. While this method prevents the analysis of usage by the issuer through hosting the revocation information on-chain +it comes with a high risk of linkability by colluding verifiers as they can store the bitmap index and use it to identify users. Additionally, verifiers can monitor the revocation information and at a later point, outside of any interaction, check the revocation status. +To address this privacy concern, `RevocationTimeframe2024` was designed as an extension that builds on top of `RevocationBitmap2022`, therefore sharing +most of its logic. + +## Concepts +`RevocationTimeframe2024` should be used together with selectively disclosable credentials - either [SD-JWT](../../../how-tos/verifiable-credentials/selective-disclosure) +or [ZK-SD](../../../how-tos/verifiable-credentials/zero-knowledge-selective-disclosure) - in order to conceal to the verifier +the credential's index in the issuer's revocation bitmap to avoid linkability. + +### Validity Timeframe + +If the revocation index is concealed from the verifier how can it assert the validity of the presented credential? +To solve this issue `RevocationTimeframe2024` introduces the concept of a _validity timeframe_, i.e. a limited time span +in which the credential is guaranteed to be non-revoked. By having a validity timeframe embedded in the credential's status +the verifier can prove the credential's validity by verifying the credential's signature. + +The downside of this mechanism is that the credential holder using `RevocationTimeframe2024` has to contact the credential's issuer +to update the signature - i.e. re-issue the credential - at the end of the credentials validity timeframe. Furthermore, +given how a credentials validity timeframe proves the validity of the credential itself, the updates made by the issuer to the credential's status - +i.e., revoking or un-revoking it - won't be reflected on the credential until a new validity timeframe starts. For this reason, +issuers should choose a validity timeframe length with respect to how frequently they expect to change the credential's status; +frequent updates deem shorter validity timeframes. + +:::note +A credential holder does not need to have its credential re-issued at the end of every validity timeframe, but only when +they need to present the credential to a verifier and its validity timeframe has expired. +::: + +## Data Model + +### Revocation Timeframe Status + +For an issuer to enable verifiers to check the status of a verifiable credential, the [`credentialStatus`](https://www.w3.org/TR/vc-data-model/#status) property MUST be specified with the following properties: + +| Property | Description | +| :---------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `id` | The constraints on the `id` property are listed in the [Verifiable Credentials Data Model specification](https://www.w3.org/TR/vc-data-model/). The `id` MUST be a [DID URL](https://www.w3.org/TR/did-core/#did-url-syntax) that is the URL to a [Revocation Bitmap Service](#revocation-bitmap-service) in the DID Document of the issuer. | +| `type` | The `type` property MUST be `"RevocationTimeframe2024"`. | +| `revocationBitmapIndex` | The `revocationBitmapIndex` property MUST be an unsigned, 32-bit integer expressed as a string. This is the index of the credential in the issuers revocation bitmap. Each index SHOULD be unique among all credentials linking to the same [Revocation Bitmap Service](#revocation-bitmap-service). To ensure user unlinkability, this value MUST NOT be disclosed to the verifier (this is done by default). | +| `startValidityTimeframe`| The `startValidityTimeframe` property MUST be a [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339)-compliant timestamp. | +| `endValidityTimeframe`| The `endValidityTimeframe` property MUST be a [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339)-compliant timestamp. | + +#### Example + +An example of a verifiable credential with a `credentialStatus` of type `RevocationTimeframe2024`. + +```json +{ + "@context": "https://www.w3.org/2018/credentials/v1", + "id": "https://example.edu/credentials/3732", + "type": ["VerifiableCredential", "UniversityDegreeCredential"], + "credentialSubject": { + "id": "did:iota:B8DucnzULJ9E8cmaReYoePU2b7UKE9WKxyEVov8tQA7H", + "GPA": "4.0", + "degree": "Bachelor of Science and Arts", + "name": "Alice" + }, + "issuer": "did:iota:EvaQhPXXsJsGgxSXGhZGMCvTt63KuAFtaGThx6a5nSpw", + "issuanceDate": "2022-06-13T08:04:36Z", + "credentialStatus": { + "id": "did:iota:EvaQhPXXsJsGgxSXGhZGMCvTt63KuAFtaGThx6a5nSpw#my-revocation-service", + "type": "RevocationTimeframe2024", + "revocationBitmapIndex": "5" + "startValidityTimeframe": "2024-05-03T08:00:00Z", + "endValidityTimeframe": "2024-05-03T08:05:00Z", + }, +} +``` + +### Revocation Timeframe Service + +To allow verifiers to check the status of a [Revocation Timeframe Status](#revocation-bitmap-status), the DID document of the credential issuer MUST contain a [service](https://www.w3.org/TR/did-core/#services) with the following properties: + +| Property | Description | +| :---------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `id` | The constraints on the `id` property are listed in the [DID Core service specification](https://www.w3.org/TR/did-core/#services). The `id` property MUST be a DID URL uniquely identifying the revocation bitmap. | +| `type` | The `type` property MUST be `"RevocationTimeframe2024"`. | +| `serviceEndpoint` | The `serviceEndpoint` MUST be generated according to the [service endpoint generation algorithm](#service-endpoint-generation-algorithm). | + +#### Example + +An example of an issuers DID document where credential `"5"` in the `#revocation` service is revoked: + +```json +{ + "id": "did:iota:EvaQhPXXsJsGgxSXGhZGMCvTt63KuAFtaGThx6a5nSpw", + "verificationMethod": [ + { + "id": "did:iota:EvaQhPXXsJsGgxSXGhZGMCvTt63KuAFtaGThx6a5nSpw#key-1", + "controller": "did:iota:EvaQhPXXsJsGgxSXGhZGMCvTt63KuAFtaGThx6a5nSpw", + "type": "Ed25519VerificationKey2018", + "publicKeyMultibase": "z3hgM9fNkhwgT5mECbj1HdKoFNZgpffwQYEV8WBVHphXq" + } + ], + "capabilityInvocation": [ + { + "id": "did:iota:EvaQhPXXsJsGgxSXGhZGMCvTt63KuAFtaGThx6a5nSpw#sign-0", + "controller": "did:iota:EvaQhPXXsJsGgxSXGhZGMCvTt63KuAFtaGThx6a5nSpw", + "type": "Ed25519VerificationKey2018", + "publicKeyMultibase": "z83F6zbD3KqaxvQhqo25LvSXzoDdpZmp3EpPVonSVACwZ" + } + ], + "service": [ + { + "id": "did:iota:EvaQhPXXsJsGgxSXGhZGMCvTt63KuAFtaGThx6a5nSpw#revocation", + "type": "RevocationTimeframe2024", + "serviceEndpoint": "data:application/octet-stream;base64,ZUp5ek1tQmdZR1NBQUFFZ1ptVUFBQWZPQUlF" + } + ] +} +``` + +## Algorithms + +For generation and expansion of the service endpoint see [`RevocationBitmap2022`](../revocation-bitmap-2022#algorithms). + +### Validation Algorithm + +The following steps MUST be followed when checking whether a verifiable credential is revoked: + +1. Let **credential** be a verifiable credential containing a `credentialStatus` whose `type` is `RevocationTimeframe2024`. +2. Let **now** be the string serialization of the RFC3339 timestamp representing the current UTC time. +3. Let **start validity timeframe** and **end validity timeframe** be the RFC3339 timestamps of the `startValidityTimeframe` and `endValidityTimeframe` (respectively) properties contained in the `credentialStatus` of the **credential**. +4. Return `true` if `startValidityTimeframe <= now < endValidityTimeframe`, `false` otherwise. + +## Test Vectors +See [`RevocationBitmap2022`](../revocation-bitmap-2022#test-vectors). \ No newline at end of file From 0142182c12b93f6c494f90125b3e8667d9fb6000 Mon Sep 17 00:00:00 2001 From: Jeroen van den Hout Date: Tue, 11 Jun 2024 15:08:08 +0200 Subject: [PATCH 24/37] fix(docs): use correct paths --- .../explanations/decentralized-identifiers.mdx | 4 ++-- .../how-tos/decentralized-identifiers/create.mdx | 4 ++-- .../how-tos/decentralized-identifiers/delete.mdx | 6 +++--- .../how-tos/decentralized-identifiers/resolve.mdx | 4 ++-- .../how-tos/decentralized-identifiers/update.mdx | 2 +- .../how-tos/verifiable-credentials/revocation.mdx | 2 +- .../standards/iota-identity/revocation-bitmap-2022.mdx | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/content/guides/developer/iota-identity/explanations/decentralized-identifiers.mdx b/docs/content/guides/developer/iota-identity/explanations/decentralized-identifiers.mdx index f4e21c5e0eb..6c28c1f1e3d 100644 --- a/docs/content/guides/developer/iota-identity/explanations/decentralized-identifiers.mdx +++ b/docs/content/guides/developer/iota-identity/explanations/decentralized-identifiers.mdx @@ -26,7 +26,7 @@ while facilitating encrypted communication. A DID is a unique identifier that can be resolved to a DID Document. This document contains data such as public keys, enabling the holder to prove ownership over their personal data, but also URIs that link to public information about the identity. DIDs are the fundamental building blocks of decentralized digital identity. This implementation complies with the [DID specifications v1.0](https://www.w3.org/TR/did-core//) from the World Wide Web Consortium (W3C). -In the IOTA Identity framework, we have implemented the DID standard according to the `iota` [DID Method Specification](../references/specifications/iota-did-method-spec.mdx). Other implementations of DID on IOTA must follow the `iota` DID Method Specification if they want to use the `iota` method name. Libraries implementing the `iota` DID Method Specification are provided for [Rust](../getting-started/rust.mdx) and [WASM](../getting-started/wasm.mdx). +In the IOTA Identity framework, we have implemented the DID standard according to the `iota` [DID Method Specification](../../../../standards/iota-identity/iota-did-method-spec.mdx). Other implementations of DID on IOTA must follow the `iota` DID Method Specification if they want to use the `iota` method name. Libraries implementing the `iota` DID Method Specification are provided for [Rust](../getting-started/rust.mdx) and [WASM](../getting-started/wasm.mdx). An example of a DID conforming to the `iota` method specification: `did:iota:0xe4edef97da1257e83cbeb49159cfdd2da6ac971ac447f233f8439cf29376ebfe` @@ -52,7 +52,7 @@ The identifier contains all information to resolve a DID, providing the latest D The first three characters `did` indicate that the DID standard from W3C must be used to resolve the identifier. It is followed by a unique method name, in our case `iota`, to indicate that the IOTA method is used. -The IOTA method is a specific implementation following the [IOTA DID Method Specification](../references/specifications/iota-did-method-spec.mdx). +The IOTA method is a specific implementation following the [IOTA DID Method Specification](../../../../standards/iota-identity/iota-did-method-spec.mdx). This provides unique rules for the protocol to follow in order to manage a DID Document. In our case, it describes how DID Documents are uploaded and queried to and from the IOTA ledger. diff --git a/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/create.mdx b/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/create.mdx index 6266a8b26df..d345a1b148b 100644 --- a/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/create.mdx +++ b/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/create.mdx @@ -20,7 +20,7 @@ This identity consists of many parts that have different functions. :::note DID method Specification -Note that the Iota Identity Framework follows [IOTA DID Method Specification](../../references/specifications/iota-did-method-spec.mdx). +Note that the Iota Identity Framework follows [IOTA DID Method Specification](../../../../../standards/iota-identity/iota-did-method-spec.mdx). ::: @@ -128,7 +128,7 @@ the Basic Output as input and the newly generated Alias Output as output, as wel the remaining tokens. The DID is only known once the [Alias Output](../../explanations/about-alias-outputs.mdx) is successfully published, -since the DID's [Tag](../../references/specifications/iota-did-method-spec.mdx#iota-tag) contains the +since the DID's [Tag](../../../../../standards/iota-identity/iota-did-method-spec.mdx#iota-tag) contains the [Alias ID](../../explanations/about-alias-outputs.mdx#alias-id). Once the transaction is confirmed, the `Alias ID` is assigned, and the DID can be derived from it, the DID Document is stored on the ledger and can be [resolved](resolve.mdx) using any node. diff --git a/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/delete.mdx b/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/delete.mdx index 86bb74c20a7..123b81764ef 100644 --- a/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/delete.mdx +++ b/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/delete.mdx @@ -19,7 +19,7 @@ There are two approaches to delete an IOTA Identity, with different implications ## Deactivate -As detailed in the [IOTA DID Method Specification](../../references/specifications/iota-did-method-spec.mdx#deactivate), +As detailed in the [IOTA DID Method Specification](../../../../../standards/iota-identity/iota-did-method-spec.mdx#deactivate), the state controller of an IOTA Identity may [deactivate](https://www.w3.org/TR/did-core/#did-document-metadata) it by publishing an update that either: - deletes the contents of the DID Document entirely, leaving the state metadata empty, OR @@ -61,7 +61,7 @@ https://github.com/iotaledger/identity.rs/blob/v1.3.0/bindings/wasm/examples/src ## Destroy -Alternatively, you can [destroy](../../references/specifications/iota-did-method-spec.mdx#destroy) an IOTA Identity can be permanently. +Alternatively, you can [destroy](../../../../../standards/iota-identity/iota-did-method-spec.mdx#destroy) an IOTA Identity can be permanently. :::warning Irreversible @@ -70,7 +70,7 @@ Destroying an IOTA Identity is permanent and irreversible. ::: -This is achieved by the governor of a DID publishing a transaction consuming the [Alias Output](../../references/specifications/iota-did-method-spec.mdx#alias-output) +This is achieved by the governor of a DID publishing a transaction consuming the [Alias Output](../../../../../standards/iota-identity/iota-did-method-spec.mdx#alias-output) containing the IOTA DID Document, without a corresponding Alias Output on the output side. Any coins and tokens in the Alias Output are reclaimed and can be sent to another address. diff --git a/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/resolve.mdx b/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/resolve.mdx index 1e5411f592d..bcaa2e04f11 100644 --- a/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/resolve.mdx +++ b/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/resolve.mdx @@ -32,8 +32,8 @@ The following examples demonstrate how to resolve an IOTA DID Document from its ### Resolver Once you have configured a `Resolver` with a [`Client`](/iota-sdk/welcome), it will resolve -IOTA DID Documents according to the read procedure defined in the [IOTA DID Method Specification](../../references/specifications/iota-did-method-spec.mdx#read). -It fetches the latest [Alias Output](../../references/specifications/iota-did-method-spec.mdx#alias-output) from the network specified in the DID (see [DID Format](../../references/specifications/iota-did-method-spec.mdx#did-format)), +IOTA DID Documents according to the read procedure defined in the [IOTA DID Method Specification](../../../../../standards/iota-identity/iota-did-method-spec.mdx#read). +It fetches the latest [Alias Output](../../../../../standards/iota-identity/iota-did-method-spec.mdx#alias-output) from the network specified in the DID (see [DID Format](../../../../../standards/iota-identity/iota-did-method-spec.mdx#did-format)), then extracts and validates the DID Document from it. diff --git a/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/update.mdx b/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/update.mdx index 13e4dc22034..a6f612934e2 100644 --- a/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/update.mdx +++ b/docs/content/guides/developer/iota-identity/how-tos/decentralized-identifiers/update.mdx @@ -55,7 +55,7 @@ You can also add verification relationships afterward using references. :::note -Updates to the DID Document are done through a state transition of the [Alias Output](../../references/specifications/iota-did-method-spec.mdx#alias-output) by its state controller. +Updates to the DID Document are done through a state transition of the [Alias Output](../../../../../standards/iota-identity/iota-did-method-spec.mdx#alias-output) by its state controller. The public key or address of the state controller does not need to be a verification method in the DID Document, since it is defined in the containing Alias Output. diff --git a/docs/content/guides/developer/iota-identity/how-tos/verifiable-credentials/revocation.mdx b/docs/content/guides/developer/iota-identity/how-tos/verifiable-credentials/revocation.mdx index 2e7c35e497d..e3dcc9d7ccd 100644 --- a/docs/content/guides/developer/iota-identity/how-tos/verifiable-credentials/revocation.mdx +++ b/docs/content/guides/developer/iota-identity/how-tos/verifiable-credentials/revocation.mdx @@ -25,7 +25,7 @@ This invalidates all credentials that were signed with that verification method. ## Revocation methods The IOTA Identity Framework supports two different revocation methods: `RevocationBitmap2022` and `StatusList2021`. ### Revocation Bitmap -[RevocationBitmap2022](../../references/specifications/revocation-bitmap-2022.mdx) is the default credential revocation method used in the IOTA Identity Framework. It allows +[RevocationBitmap2022](../../../../../standards/iota-identity/revocation-bitmap-2022.mdx) is the default credential revocation method used in the IOTA Identity Framework. It allows issuers to control whether a credential is _valid_ or _revoked_. To do so, a revocation list (represented as a bitmap) is stored in the issuer's DID document. When a credential is issued, a unique index from the issuer's revocation list diff --git a/docs/content/standards/iota-identity/revocation-bitmap-2022.mdx b/docs/content/standards/iota-identity/revocation-bitmap-2022.mdx index 5c7b89aaa8d..bf40002296b 100644 --- a/docs/content/standards/iota-identity/revocation-bitmap-2022.mdx +++ b/docs/content/standards/iota-identity/revocation-bitmap-2022.mdx @@ -15,7 +15,7 @@ tags: ## Abstract -This specification describes a mechanism for publishing the revocation status of [verifiable credentials](../../explanations/verifiable-credentials.mdx) embedded in an issuer's DID document. +This specification describes a mechanism for publishing the revocation status of [verifiable credentials](../../guides/developer/iota-identity/explanations/verifiable-credentials.mdx) embedded in an issuer's DID document. ## Introduction From c79685120725ce575e2d115445645d9e64c89966 Mon Sep 17 00:00:00 2001 From: Jeroen van den Hout Date: Tue, 11 Jun 2024 15:13:33 +0200 Subject: [PATCH 25/37] feat(docs): add Identity images --- .../domain-linkage/create-and-verify.mdx | 2 +- .../static/img/banner/banner_identity.svg | 83 ++++++++++++++++++ .../iota-identity/domain-linkage-diagram.png | Bin 0 -> 91616 bytes 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 docs/site/static/img/banner/banner_identity.svg create mode 100644 docs/site/static/img/iota-identity/domain-linkage-diagram.png diff --git a/docs/content/guides/developer/iota-identity/how-tos/domain-linkage/create-and-verify.mdx b/docs/content/guides/developer/iota-identity/how-tos/domain-linkage/create-and-verify.mdx index ef3a313e224..87a5ba312db 100644 --- a/docs/content/guides/developer/iota-identity/how-tos/domain-linkage/create-and-verify.mdx +++ b/docs/content/guides/developer/iota-identity/how-tos/domain-linkage/create-and-verify.mdx @@ -31,7 +31,7 @@ the same entity controlling `www.example.com`. The DIF has approved a [Well Known DID Configuration](https://identity.foundation/.well-known/resources/did-configuration/) draft to standardize this connection by introducing the [DID Configuration Resource](https://identity.foundation/.well-known/resources/did-configuration/#did-configuration-resource) and the [Linked Domain Service Endpoint](https://identity.foundation/.well-known/resources/did-configuration/#linked-domain-service-endpoint). -![Identity getting started](/img/domain-linkage-diagram.png) +![Identity getting started](/img/iota-identity/domain-linkage-diagram.png) ### DID Configuration Resource diff --git a/docs/site/static/img/banner/banner_identity.svg b/docs/site/static/img/banner/banner_identity.svg new file mode 100644 index 00000000000..61ffbf9bcca --- /dev/null +++ b/docs/site/static/img/banner/banner_identity.svg @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/site/static/img/iota-identity/domain-linkage-diagram.png b/docs/site/static/img/iota-identity/domain-linkage-diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..0c3f410d9499f3b72b18d831e0384ac2c776add4 GIT binary patch literal 91616 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

d2vlk8$)1^?LXA%MZj5L(>@^|!(0#~_K~{2}}M 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 literal 0 HcmV?d00001 From bb7a7e5e50e71ae528963f7080ff9b1fe257ff79 Mon Sep 17 00:00:00 2001 From: Jeroen van den Hout Date: Tue, 11 Jun 2024 15:43:13 +0200 Subject: [PATCH 26/37] fix(docs): fix links --- .../iota-identity/explanations/about-alias-outputs.mdx | 8 ++++---- .../explanations/decentralized-identifiers.mdx | 6 +++--- .../developer/iota-identity/getting-started/wasm.mdx | 4 ++-- .../how-tos/decentralized-identifiers/create.mdx | 2 +- .../how-tos/decentralized-identifiers/resolve.mdx | 4 ++-- .../zero-knowledge-selective-disclosure.mdx | 2 +- .../standards/iota-identity/iota-did-method-spec.mdx | 4 ++-- .../iota-identity/revocation-timeframe-2024.mdx | 10 +++++----- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/content/guides/developer/iota-identity/explanations/about-alias-outputs.mdx b/docs/content/guides/developer/iota-identity/explanations/about-alias-outputs.mdx index c7c160a0e41..9cd94f96897 100644 --- a/docs/content/guides/developer/iota-identity/explanations/about-alias-outputs.mdx +++ b/docs/content/guides/developer/iota-identity/explanations/about-alias-outputs.mdx @@ -17,7 +17,7 @@ tags: The IOTA DID method uses Alias Outputs for storing DID Documents. Alias Outputs are created via transactions, -and require a [storage deposit](/learn/protocols/stardust/core-concepts/storage-deposit/) to cover the data storage. +and require a storage deposit to cover the data storage. The deposit is refundable upon destruction of the output. Each Alias Output has an `Alias ID` that becomes the basis for the DID, @@ -27,7 +27,7 @@ and which can be transferred through transactions to update DID Documents. The IOTA DID method uses the IOTA ledger, which is baed on the unspent transaction output (_UTXO_) model, -as well as the features of the [Stardust](/introduction/stardust/explanations/what_is_stardust) upgrade, +as well as the features of the Stardust upgrade, which are fundamental to the IOTA DID method. The Alias Output is used to store a DID Document on the ledger. @@ -38,7 +38,7 @@ The state controller can only execute state transitions, which update the data i The governor, on the contrary, can't update the `State Metadata` but can change controllers and even destroy the Alias Output. -A controller can be either Ed25519 Address, [Alias Address or an _NFT_ Address](/learn/protocols/stardust/core-concepts/multi-asset-ledger/). Only one of each of these types can be set for an Alias Output. +A controller can be either Ed25519 Address, Alias Address or an _NFT_ Address. Only one of each of these types can be set for an Alias Output. To create a new Alias Output, a transaction must be made that includes another Output as input, a Basic Output, for example, and the new Alias Output as output. @@ -46,7 +46,7 @@ a Basic Output, for example, and the new Alias Output as output. ### Storage Deposit The arbitrary data stored in the `State Metadata` of the Alias output must be covered by a -[storage deposit](/learn/protocols/stardust/core-concepts/storage-deposit/). +storage deposit. This helps to control the ledger size from growing uncontrollably while guaranteeing the data is indefinitely stored on the ledger, which is important for resolving DID Documents. This deposit is fully refundable and can be reclaimed when the output is destroyed. diff --git a/docs/content/guides/developer/iota-identity/explanations/decentralized-identifiers.mdx b/docs/content/guides/developer/iota-identity/explanations/decentralized-identifiers.mdx index 6c28c1f1e3d..fb3dcdcb903 100644 --- a/docs/content/guides/developer/iota-identity/explanations/decentralized-identifiers.mdx +++ b/docs/content/guides/developer/iota-identity/explanations/decentralized-identifiers.mdx @@ -119,7 +119,7 @@ Inherently, IOTA provides some unique features that have a major impact on the u ### Availability and Accessibility -DID Documents are stored in the ledger state and are covered [storage deposit](/learn/protocols/stardust/core-concepts/storage-deposit/). +DID Documents are stored in the ledger state and are covered storage deposit. This guarantees that all nodes will have an up-to-date copy of the latest DID Document. Resolving a DID into its document can usually be done by any IOTA node in the network. This solves many issues regarding availability, accessibility, and synchronization. @@ -127,7 +127,7 @@ This solves many issues regarding availability, accessibility, and synchronizati ### Layer1 Interactions DID Documents are stored in [Alias Outputs](./about-alias-outputs.mdx), -this allows them to directly interact with Layer 1 artifacts like [NFTs and native assets](/learn/protocols/stardust/core-concepts/multi-asset-ledger/). +this allows them to directly interact with Layer 1 artifacts like NFTs and native assets. For instance, an Alias Output representing a DID can hold native assets or control NFTs. Transferring funds between DIDs is also possible on Layer 1. @@ -140,5 +140,5 @@ It also allows more flexible and complex management of DID Documents. ### Secure Storage IOTA Identity provides a -[Stronghold](/stronghold.rs/welcome/ 'Stronghold is an open-source software library that was originally built to protect IOTA Seeds, but can be used to protect any digital secret.') solution +Stronghold solution for managing secrets securely, without requiring developers to reinvent the security wheel. diff --git a/docs/content/guides/developer/iota-identity/getting-started/wasm.mdx b/docs/content/guides/developer/iota-identity/getting-started/wasm.mdx index ad1baaf48d3..a470f581673 100644 --- a/docs/content/guides/developer/iota-identity/getting-started/wasm.mdx +++ b/docs/content/guides/developer/iota-identity/getting-started/wasm.mdx @@ -83,7 +83,7 @@ npm run build:web ## NodeJS Usage The following code creates a new IOTA DID Document suitable for publishing to a local test network, like the -[IOTA Sandbox](/iota-sandbox/welcome/). +IOTA Sandbox.

+
CoreDID
+

A method-agnostic Decentralized Identifier (DID).

+
+
CoreDocument
+

A method-agnostic DID Document.

+

Note: All methods that involve reading from this class may potentially raise an error +if the object is being concurrently modified.

+
+
Credential
+
+
CustomMethodData
+

A custom verification method data format.

+
+
DIDUrl
+

A method agnostic DID Url.

+
+
DecodedJptCredential
+
+
DecodedJptPresentation
+
+
DecodedJws
+

A cryptographically verified decoded token from a JWS.

+

Contains the decoded headers and the raw claims.

+
+
DecodedJwtCredential
+

A cryptographically verified and decoded Credential.

+

Note that having an instance of this type only means the JWS it was constructed from was verified. +It does not imply anything about a potentially present proof property on the credential itself.

+
+
DecodedJwtPresentation
+

A cryptographically verified and decoded presentation.

+

Note that having an instance of this type only means the JWS it was constructed from was verified. +It does not imply anything about a potentially present proof property on the presentation itself.

+
+
Disclosure
+

Represents an elements constructing a disclosure. +Object properties and array elements disclosures are supported.

+

See: https://www.ietf.org/archive/id/draft-ietf-oauth-selective-disclosure-jwt-07.html#name-disclosures

+
+
DomainLinkageConfiguration
+

DID Configuration Resource which contains Domain Linkage Credentials. +It can be placed in an origin's .well-known directory to prove linkage between the origin and a DID. +See: https://identity.foundation/.well-known/resources/did-configuration/#did-configuration-resource

+

Note:

+ +
+
Duration
+

A span of time.

+
+
EdDSAJwsVerifier
+

An implementor of IJwsVerifier that can handle the +EdDSA algorithm.

+
+
IotaDID
+

A DID conforming to the IOTA DID method specification.

+
+
IotaDocument
+

A DID Document adhering to the IOTA DID method specification.

+

Note: All methods that involve reading from this class may potentially raise an error +if the object is being concurrently modified.

+
+
IotaDocumentMetadata
+

Additional attributes related to an IOTA DID Document.

+
+
IotaIdentityClientExt
+

An extension interface that provides helper functions for publication +and resolution of DID documents in Alias Outputs.

+
+
IssuerProtectedHeader
+
+
Jpt
+

A JSON Proof Token (JPT).

+
+
JptCredentialValidationOptions
+

Options to declare validation criteria for Jpt.

+
+
JptCredentialValidator
+
+
JptCredentialValidatorUtils
+

Utility functions for validating JPT credentials.

+
+
JptPresentationValidationOptions
+

Options to declare validation criteria for a Jpt presentation.

+
+
JptPresentationValidator
+
+
JptPresentationValidatorUtils
+

Utility functions for verifying JPT presentations.

+
+
Jwk
+
+
JwkGenOutput
+

The result of a key generation in JwkStorage.

+
+
JwpCredentialOptions
+
+
JwpIssued
+
+
JwpPresentationOptions
+

Options to be set in the JWT claims of a verifiable presentation.

+
+
JwpVerificationOptions
+
+
Jws
+

A wrapper around a JSON Web Signature (JWS).

+
+
JwsHeader
+
+
JwsSignatureOptions
+
+
JwsVerificationOptions
+
+
Jwt
+

A wrapper around a JSON Web Token (JWK).

+
+
JwtCredentialValidationOptions
+

Options to declare validation criteria when validating credentials.

+
+
JwtCredentialValidator
+

A type for decoding and validating Credential.

+
+
JwtDomainLinkageValidator
+

A validator for a Domain Linkage Configuration and Credentials.

+
+
JwtPresentationOptions
+
+
JwtPresentationValidationOptions
+

Options to declare validation criteria when validating presentation.

+
+
JwtPresentationValidator
+
+
KeyBindingJWTValidationOptions
+

Options to declare validation criteria when validating credentials.

+
+
KeyBindingJwtClaims
+

Claims set for key binding JWT.

+
+
LinkedDomainService
+
+
MethodData
+

Supported verification method data formats.

+
+
MethodDigest
+

Unique identifier of a VerificationMethod.

+

NOTE: +This class does not have a JSON representation, +use the methods pack and unpack instead.

+
+
MethodScope
+

Supported verification method types.

+
+
MethodType
+

Supported verification method types.

+
+
PayloadEntry
+
+
Payloads
+
+
Presentation
+
+
PresentationProtectedHeader
+
+
Proof
+

Represents a cryptographic proof that can be used to validate verifiable credentials and +presentations.

+

This representation does not inherently implement any standard; instead, it +can be utilized to implement standards or user-defined proofs. The presence of the +type field is necessary to accommodate different types of cryptographic proofs.

+

Note that this proof is not related to JWT and can be used in combination or as an alternative +to it.

+
+
ProofUpdateCtx
+
+
Resolver
+

Convenience type for resolving DID documents from different DID methods.

+

Also provides methods for resolving DID Documents associated with +verifiable Credentials and Presentations.

+

Configuration

+

The resolver will only be able to resolve DID documents for methods it has been configured for in the constructor.

+
+
RevocationBitmap
+

A compressed bitmap for managing credential revocation.

+
+
RevocationTimeframeStatus
+

Information used to determine the current status of a Credential.

+
+
SdJwt
+

Representation of an SD-JWT of the format +<Issuer-signed JWT>~<Disclosure 1>~<Disclosure 2>~...~<Disclosure N>~<optional KB-JWT>.

+
+
SdJwtCredentialValidator
+

A type for decoding and validating Credential.

+
+
SdObjectDecoder
+

Substitutes digests in an SD-JWT object by their corresponding plaintext values provided by disclosures.

+
+
SdObjectEncoder
+

Transforms a JSON object into an SD-JWT object by substituting selected values +with their corresponding disclosure digests.

+

Note: digests are created using the sha-256 algorithm.

+
+
SelectiveDisclosurePresentation
+

Used to construct a JwpPresentedBuilder and handle the selective disclosure of attributes

+
    +
  • @context MUST NOT be blinded
  • +
  • id MUST be blinded
  • +
  • type MUST NOT be blinded
  • +
  • issuer MUST NOT be blinded
  • +
  • issuanceDate MUST be blinded (if Timeframe Revocation mechanism is used)
  • +
  • expirationDate MUST be blinded (if Timeframe Revocation mechanism is used)
  • +
  • credentialSubject (User have to choose which attribute must be blinded)
  • +
  • credentialSchema MUST NOT be blinded
  • +
  • credentialStatus MUST NOT be blinded
  • +
  • refreshService MUST NOT be blinded (probably will be used for Timeslot Revocation mechanism)
  • +
  • termsOfUse NO reason to use it in ZK VC (will be in any case blinded)
  • +
  • evidence (User have to choose which attribute must be blinded)
  • +
+
+
Service
+

A DID Document Service used to enable trusted interactions associated with a DID subject.

+
+
StatusList2021
+

StatusList2021 data structure as described in W3C's VC status list 2021.

+
+
StatusList2021Credential
+

A parsed StatusList2021Credential.

+
+
StatusList2021CredentialBuilder
+

Builder type to construct valid StatusList2021Credential istances.

+
+
StatusList2021Entry
+

StatusList2021Entry implementation.

+
+
Storage
+

A type wrapping a JwkStorage and KeyIdStorage that should always be used together when +working with storage backed DID documents.

+
+
Timestamp
+
+
UnknownCredential
+
+
VerificationMethod
+

A DID Document Verification Method.

+
+

K`fs* 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 literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/sandbox.png b/docs/site/static/img/iota-chains/sandbox.png new file mode 100644 index 0000000000000000000000000000000000000000..2071da12eec6d1061f59a1ef3601568d036ece2f GIT binary patch literal 43865 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%0ABW3xx#;0(-KKLF)@(GytdiGAn;V<^aSAW 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Æ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

ZgHs%f{PJbd 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 E0rJJC1^@s6 literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/firefly/select-send-assets.png b/docs/site/static/img/iota-chains/evm/how-tos/get-funds/firefly/select-send-assets.png new file mode 100644 index 0000000000000000000000000000000000000000..22327dbb652d09b7a8ee4c8413981e66b601abe9 GIT binary patch literal 23432 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 d`@c>(=AvEW1o5Xsx<8*{{>!Vc1!>O literal 0 HcmV?d00001 diff --git a/docs/site/static/img/iota-chains/evm/how-tos/get-funds/firefly/select-shimmer-evm.png b/docs/site/static/img/iota-chains/evm/how-tos/get-funds/firefly/select-shimmer-evm.png new file mode 100644 index 0000000000000000000000000000000000000000..f1a3b2dcfd0a4a3a80e3f3c70394c5ac02482da3 GIT binary patch literal 30875 zcmeFYbyQVf*Drnq1qA_-?vn0q5a~v`ySqCDq(MYFrMtVkL!>(o-3^EMZG65@z4!jc z9q$L{=0LTGDmV{B$=MCj;dYeZ<|YGw=qxz1b3Eg(P>y@iaS;`#CTG9aoPWn2F` z#d$3zsv$Z1^)(9AHpHnT%U|xJ{eVg@JBFLO!!*mFYtr_qx7a8cdvwWBH2x|H2%9S@=&R6PY-(Seh7{<4oduW) z3d)HK3jTdFz!p-xqIt!-^BtV7Y@S4D%bS!$LXC(L&{jCgDoB5}GfNl2|@a z(nWr;=;%oADfADkDn%^)LU;qcez2OoLrl6HkE-77x^~Jp+O&PL?B)9_pJ8M#=@rWo z+r&UX!bnNzPnDMpUtaej$0QmJi_62cUOLGxDZ1FDfmg0gE(_ekUc88Qjl;^7ZWiEa zF~do@4k0Q2P}IHM%@{)`cHi&Rv%x+p9RDf}i;;QPZT)qH>Va;KzuLfLa9(g$VXi{! zw@X!UbB|ilr0Ra!ec)PiYvr($dY70!vg9|yPXY)=in=5+O){Z@EUDz4_kyK5#POd> znJ_ugmF8!Z6j_1?^2j0+ArhpoCaJLOmUmrq^G;VkjaLb&(e9Z@~;=Z6`1!7Lm zo>@@8c)ha%LszY+)y)WcLy>wRW86; zU44g1Eq~QG*5tvpePttS;myB$Vn40LlTiyOovRt3T&mJiTn08)bb5w1`bKoFRM-4W`?}PDy-5B(zb#|rejbh&`f&%^Y@gny6 zG0+OTnmIEO^T84F*c%#i$qR}6MFRN7OKj@sXv;-U@8aS@=fX^9V{byw$jQk`&%i{_ z#6%0spmlJwcGPpFwRRwRCh<2KLPib-_GY$@W;WJ@&ouS)ZJZo=iHU*hgnwV3m94b& zKge4<{KW-;AM~zzw)Bj24D?o3^#6K?gQKuBK;*9l{crDZPz25>y}Xfwjg!5Bk+8Fo zwIj*Dk}x#*$NjcW_LhIPV`xBcWNBmtOmzUB%J^@O6cv}2`^O#6EHE*%vi)-x!0dmU z>1byBPiFnw+Mcic+0MT%1i1YlbpLJk-}nA!GB8V8noG#W!0CB;;zGQ{&(G&Fv@tL< ziD8yG#4 z0*KR@0d$!44H((=3=C)u*bI$mSvZ&&X*u;7SZUde^%#u|I2aAtI2r$igsi<8pp|-- z|GKJYQicF2PGAv+oQ(Rk9D2q~v@8rv9JHK_Ol-6)1_p-g`o@f$1}vO^NEsS%iP+d% z=>g(2v(hs$qPMj+`E%i!;amc8;=II6bPWF-k+aluGzMe41#AXjtlqPp0tEhy z1AE~Tv^Uaow6RyTv9aVOekMWqeCIzdO9RKrP|s0MNYBv-Aj-hR!o|SI#l)$|$j-&e z!o|u!%fQUV@GtXi49$$){!g=?4-X;F-$X8E<^Vk3?a$EPPLzU?-QT|b?W?8PpQA)b z_~%e?=^6ZO3l4hDMuvaZ3DEl6B?D7EYZD{Ddi8BCgOMH+qcI@0XGLOR zFl49IXJQ6aido;-(Ab#Sh?AZ9->Ey;7(2S?*&7L%0DJ^^1*qpAUJ+9K5ftUW&vr32 zdX@sfFj@vi+J7>P@h^ta|FvQIXPfc&9rMutFFfJ-GvQy13~=Ay#sK35*h2b$7{kAK z_H1_k2mkyfi~qqV0Hpu(kpC8c|HH2Tu-QFoyYXp~ zQVp7P;IpQt$tF#4`-Tg1mKGe=D{Gc3Z4eqOv2;>jX7iJaw;PYD=L0fw^w%LZJ=m@R<}OVL#CdVW-Szn*onO0@Bjjd`m?e;(u9j!Ua;a4=bl%$d#y$#;eSOb4AtV@21+&{T|Y zMvD#A7pYbAqu%F`)+J*5&k{10pNy69MI{cMS_ur#$@$p6r|v>| z<@WAd#U%Y^E1(p-bJ}vb<`o5(p%%8G{p?^PTVX=>RfG4I%LwfkrsQM$vU|+mGkO87 z>2qCG^NF>8YphxYpM;aqPayumZ@9Q?`=DyfBj%WwT{gq)(_1hY?f&-o_?O49p?hR& zvWfQnI~OIiB`z|%+u0X)=zwVG;}V?`w02>|WTbTGsiTk$&&!ylTyh9F^7PyV%=7W) zYhUVKWwLtm85CS!Uh^kQ%4P5$#w4%p8x%0gHcgMzLtHj?7x|EVe5jk4nQnKA0$I17 z&L3v%H)2U{tUJv4k}CrEmz~f;Mm8uZXx1in!`!^~>J*jSnkPg9UY+MPmFa&hLsTtk zrBSU-%hOJ9?%f}!p!+_+E}Lx=uL1 zt_BUBSq@_DylBiSOO?z$>BW0==2Nl!ScaO!9zsIF;Cm}M^I2Z`$jfG=S8F(-E>wEK z*+XZ4p#@Jt+dZJ$_*7B3kwa5XO8;Es?e0wCH$t2t?^&piPid5nmJ9FWn?iBQaQ$GB z_|Td4e)?S;{D#RJ8fla+_~=A%6o1Sk5H&h*qvmDTv{Y?26>wFOJkCJ}2PlSem5a}` zc-O_gOM13JQ=BUg{uRM65gpkVYrGiD`7-A8G1btaLoyzgU_f!Cw|@v}TC*2;Ail@I zlZpSK{Ptien%;!23+y~mWTBDUe8Dh+-Smhiun=Xa{@yp{ds(8-i{b0ZBp+uDhn!s=pm9)9 zUGBe+4wDehi2>9&!)FZjI||Cq40E6){jLg$l2*-HG%!&iGz($fm$VaS0_ z^X)Oe?Roa+4>gvW+)L7AkB{36Clv{|_Y0&K&71gNwQk?l@!k-m$Y9LqFov_0Buyre z1BZb8i8w78IgN7x{$Kl@{PgLwU4ge6U^%$t z&9@ty(l6Pb(vBHg2>lvKtoS#qZ~%y-Y-(o}OPvrr_- zG#>pEm4I@C{>h!7uBma?VYhH(Sfdfq_vb^?r0QduSJ2JD0_k$nT#ybOh>(gHwWtgU z1lS#z!sJvFdUfcJ+TO^rZ6_UAC0*5H+sr$a{I-Y3=|6{$KpDeFC)1DmSzRqA!XR&D zokmB~zyZU|^8A4D8NR`jqQ~y}EY>Z931QK%-zPKgy7ecnmM$>8*q_<@JFDjAlmr4g z+553;DZ8Z75*aCx=HA*^;Qn#!hx!PZnAkpL`@<6-0bRclGX!btq+Lh5XKYV!22uQC zcR4cJziFaUjpvx>Nz}UWIK6neJZ4LJ9rPLz?nHa^OyQIfne~yc;^}=xefBWKh9C?} zR5-^aO?u&KGQoL&v;{a8Z(+L3W_~(I5I-9L&Wbk?>%@RydAybNi}~mit4wL@G?|lt zQ`&r5#xHl2Zz#IQr(C))YO+E{L|*pJmoj}+&-7`OMKTz?P#~+Is@NHq>Y;Y_K-QX4 zvxqY}lH3h-va@O7>UhRlGiX?m5b_#{ZyRr)m>6M67MAb@>z(45DD9LdkxKdE=Yg{+ z4YgKx>L;&#$z|_HqDCjF^`m6+a`&!L?2fBP6Ni1x-m6Im*QH-rFDct2R3cZ$u66cH z#7EVtzfSV<+s{O71c$(#%b3u+*v^gk7~S{t0SDRd2OI6q@1JN|T-EC?Dp8wz+-byC z#{$l|1iBYBQTB7B54%exw1A&s%20uYx!7yZmJG7(De=i#{Jgt_ug3WbP?FlwN>1E8 z5;SB^r38E&--`)9iES>$F^dcl;eg7EWDHRKL&sCO=jAl^T2kvZA>c@mu?^3s4PQtM z4c=~3r%%_f`41SLvAuZGgsnOQq?4fliIaNpOuN1WOjhdW!;58&qOxPpyFeuKVV~>c z-WkODPzivA;j(%3Fd0rmFPFVeiHJMDG`M#Xrt!>cCVSKev*(VkPEk%UVnw_qn2mkn z^Fk^~V$bv$LmbwsjDv=CFr8_{BJis5WzQYqS>tKMf;wK(z zq_a@>t~Y5#jLFiV58a{_2gw*}?8i>MZ}%^&hAK>ZL_i{lN2C1$OTK$Urjb)zvfHye zb0}lRrMT?h@`Hb2Pw=|V#9FG|vk|miaqx+5bAC$xBCl$&BVh2G_u*>kz2eK3y*fQU*%s@dXGj<2 znmA?>5}#?H5a4_^Nx+Tl^U1)q- zqEzCNU;0%16pr(%eM3u!SK&u|-fUQ(r}Gj`UcGmZ-mNU55g)kgGDKpIhi{AOk1BsU znl5}Xns^%W8^%o{?S7Ao`O!`skWb4y-!fy`Jd2|4Y)T^#(VARwCZ?NiW_92uotUH!>}-6MQ*zwq$6SYxoA|={UO%p9j70v?6-j^M1gs4Uv_aJbeycWn+6^&{h}J z+RDd4t#!bi(1pPqfBGw?EJnxHQ}=VPAI-BtRyBRc7_BE1@G2%&qdgv&urp!fCfbhQ zgviPaVbJlaTjciHxS=2m--B;Yo-mgGyxYC&$mp?#P2A-l5(3v{$;NCmppNgoCvDwo z%t97(`eWv&vQDmk)@REP6`%ER2S>Np@|Lq5AVT_?oj2YiY;4xjM(_Hy#QB-YM-n|7teFMb_)6*QDE`(JqoS5!%dj zsL!YuDO!?MQsm;)v^}zMHxN5;YT;T3qH1p<-d1Vgw;vTTapp%LME{%-`uB+Y|LNF2 zBmL}U2AzJS^V6Dj8~EOty`VYE7ybesAAtmfCki%xNIWnL*Tal47A^8CNC18OEQu{?cO4Fx}J-H@=D ztK-94MFJgaM5v59bIq%ub%J-n zbL(LO&_9ICQ(2o*&}N4uC}`;>VUQa@Z4H&*iSMmCOjyNsn_&verlP(q&ci}g&3#f; zq(LVry2|Jm$9xMz!>9bktM~@?rTn+#z#;JDS7gp8+$;Ic%=J<8<@5PX3pR~C9uS3; zus42KRBU;^s@3c0^I@>Pvd*;H3KW|EPi2QPS`I}$D*L#f=J1G9U*B;?@!*fCt&psJ zS)m-@CzSJ$5^5ueUP*z+&o>S$t8EPS<|l@m)RD+?6TX1_SACF=O00Ra2OBfckAMPU zY}WArtTzP(joxx-iPWtSYpF5f2YC|BuTiacE;Uj{lprV!!hA(taz8}N^-LLt1FeFN`ZqZgPxLr=w)o&kh zpPUy#n7SJrFe;7q*$y3F?e%Qe7Qrxkt70tQxDxGR%~hMeAHkb>+hNLbHccKz=juil zxic8*RA7RePmIu!6Cc?%vo~~q8%9Y>n`5L8->b>=KB!ATr1ueC8$WrZH$S@TW^W%W zFU7j+tF+}(Z5PBvN$FDjiag!hZ(MchmuuH$jB1@V3AghR)M|h9`$Jn`36wcb2Gf?y zUF_%6FUolz2!rh5-@N7UzMA7JV06*q{;~CD+;AI>@v;cKJP-DGYW7E1xE=>gkc?H* zcMZ8=pXJBMh=prBUgm4?<4Q!PY`iimdi?2~D7>tC+?Y;lRB-u6vWUYGrT7c|ey1@I zgR!kiDgHuCe!1=y0oU+CI-T)l?o!Pb5)#6uk55zdMYv^}>#iga-PUQbCg^!B=rJX# zR++KW%O=Z?M>D}(h;7+iYxS<^K;jn4@B>Cx2ER{n-(G7l+oc92HE4Fja#w{UB$%Sp zX?`+S=K>`LRZ>t;WLN%ntIp{cdh%{Do5*Dq$qES%_o7j6e%rJZnVwE?z39aq7EhDs z)x;L?_3O9T*pXp12TIBU#Io)<+8sdTY#Jbs>!U8~y7WpZVc{MYv+p0bNAYIM_0Glf zsA;K5*xAdb_k)nOXKtFZtE)$MH#_AB%y}#91-W>+Yc}Uky~KjyVRe_{T4=PDyp*wV zusYlD8@}Q-F*jUBv)}4pVLy6aziiB@KA|%(O?UQWw!vfPzlUkK6?Hu*Jzd7}=CM6D zb$2!&K%w{QQK0u3LCf+;sit|JBPua;Ydt_lwtUM2^7p6#cW8*7Pc7CgUd?J)E;po` z;5UDdlQ!quqv+r2Ya?j+>aTXob9pucZ}GIWTiLKZAJ}M+pfZKe|^@0+P)ehLNUdreD>|t%eQeUM=W`1;>#>mf z%R+&hJLMGxd)Ft_voHxaw>=(2V+;m|ahPfAxvtCf~B{Qc_}? zZ|xv{Pa5NA&FQjfH378kVBR5Eg+IaPcjb>CoD_5w3Yz-cVrHD6jjzteQ@xI@NmX$V zi9v2o^Pcwbk+uUFGRwF3C4Bdg3X1~A#+x>b)^@P{h5;k9`A690J4a+3mji=iKTYj4 zuBh6O2vby?t<>v>vbg6J0LG^3xQ{1^Txd^{XnRpb$7kqkMDosJ0kq4K8+=>SF4ugW z&3;Kot;I~7(NODlyPy9i7|(buGpDoM~`x}H=U%~!iodt4baI3JkO#5Lj|K(6<@1bv#vAZ^;bO%^88 zeai2wzT6oM?4{DEwV+hZ2}L2&)*ri&ghamHN>phj;^GOe-;rx|KlIypv9&FE*IJD7 zrF;=`94ZliO^9sDXuyWW`OT@>ZKtpJK3%Cc|Aa8EbPoK`G`O+WCwMCq2T)tiwwnO**}riEM;2QtI_SOG-#rRD_|GuFC? z^9VozrrK;GNly?~ul-|h>qEi_nMf3Vhp*p5VOx=+kBa{nC_9cqSVT@4%#WLn4b5H& zFJ3&NVi0s3I(w|pQ&4>1;JB#`&d#o$hVUN>(o)k-j4EbGXaOeW zdYR)3cwb(v&WN5aKKXbiZ=9}xu?tcQOITL^GH+s}B&t=(Ks#^9YaUEMS+il^ARY{F z0>0auN$P%R-pXnI^8UR{LZ2zaFAlbF*5qqforMbS7^F6}jtL~~o>`*Q#0p#J9?~f< zv19Mn0JSjohipyo#qMtj9Z&;dXIIzG?*@{hnc}Sao7aeo<~!@>24KwFR1#BgDOhA10BPNW5DG%vhc zHJMADAJvvPGHGlS zhvn5y3bW_CZ> z0{Yzy88BCAnv_Q^G8#2yhPUSHFev*+U6gdX>bu#89 z!`_62XI+TtrDmZ>hQT{!yhDz5@6cs<_YU)u!1B+kq^D-KTV-Vq+aK}Bxac{&q{PIR z>b9z=k!MU))T5=6XU$P(w1Z&q;a9 zkb%ZeM_#{0?9xB|Tpt?TUxuBD9){%Cp(oVGUKFilvj2q_={fucqHZ9v2EyJ#(I+ZJ zVWG{L)zejb&H~#X3g29Iij&=ZVm}7%@l82=HU%(*I}!FijK7i@3ON9U_=6t&Gr{>E z8KcwRg1^<{YgGoK`Wy8JhGbe@22&)U>K?fL*HR7WX>%(($8DilKk#4|>41z#g;6)r z*X=n^U3umUfTCCj)>{}rbjm(BdeL?qgF_U9W4FRX&4kjeYvZRNAU~0l*YurGD*(Wh zXq}2LdmX#Q+1d5JDZ}B|YDzZH&t!o-<+FF>Cq*HlJ)?Sb@b;>6!|OLurRjcq8x}yK z^3hJ9^eQ1Zc+#ThRRfSaot)N8w|%^qS>k<3FE{e6TM8axLPFRtC|)J(kK72m?JUWW#Y`LCV2j^5$FX;k?tG|swRy=!?PwHo8gcjNOY!Autyfk|6F(moJJFF z>zeJ4fi+vkuz)1G#G> z93{V2#aDOhmRK^kU`y#;I8*$*2YW`Ke#ih#X*H?#fv?v zu#gJ0zOhlieiouiV@ym!vIFey5{J#KtKh5q#qR{fyw*1mSB;m)-L+R=pBG0jRF_?J zxmnj!bnwojw`LOX;Hyt$vf09)Sdv|iOwLE4tIe>+s*tpLR<*6hT(#grCETv2cJB{+ z=+SbC?UmJQO(RE)i%Knj#521beX>b_GBn0t4pC2>nL@^>`*RfQHg|>y zgD&x*{`EwaJmz9q?p~z*FH*KbnN{79a++pjy{Q87%tGb{} zViL6c?aVLZzf{`sthm7tJ9M2&&Dd<^Y1{#HlPjZU+I0+Coc0aBKv9c~GF~TUpL!z} zfA<<9hIR?Nkks!?q7l1Ixhy8GZK%rDVtMu5GHur4QmuB~l>7#^V{F}h0Zb0#BE@{@ z*6Az>+xThSM_!yXS}id^xc10&D-T31tXoZxJH6t$=Acv$CbNY?nH0H zfSJfu@s{iDKfCVGLMBNbz557U)a*AmOKgpD`fLn0wvSyzhVW;bNLHlWLaiiMjC$&x zz(_8dk-Iw?xuRsU#8zNMcjp4$j~AuMz0tMyRDuwf7pp}s=^ua#zm;W-`YNvz7%#B^ z6f7Tmuk3L4@TF{S_F%+_Y2oR7MecI_1kW3=;}G9gpo>XNs!I3GPc2ODY-WQX$6j!$ z{`7i8^VJ%Z4Z^#O!opDQ$9uL&IP!{UBF~EzkDd9}Im&n)InCazr@NO?u!~AcQrHX0 zU<(DeOaEI?w`kDsS|yVA>m;)^+uvMTUHEkdzY{pGnq2B_Eg&Idqqa-?c&5rX`O`Kb zo|K7}5j6>h{4o8A@OBc z)bZ&?(mv`;qH@}=%&mQoI|Hq-T)XD0G05%azVQ7+PE>GI#Ok<58Gw1MMwl_TOlSeH zCx7wE+QWh_gKba3i<-D=aIulpgC%|~h##m14-NUW#s5^fk3Lw00vw7{znVbC_$J;r zN2%TM)=7sBus!qPKAPvr2%I`w#81(nxNyA15J1qn=jY&EmDW?4szZuTeFbE)z1nc~*C^x=5ej}2MhCGz0wnnLA0oFW=_#MC0( zzH4+tGgSHnsk8pRNk|&mYq~O|loH-6fD?Vi2gJ6Q6;IP{C+x`l75&K`D{lC@@lFh;h@M6iO2lty@m`xNFZI&dGAt8 zZeM3{X^WS8b;tY>u=S5eCYRk4hJ>q6KN6UUlaId^%r*Pu&Nl1+88>BrJ?!2p*nryGux7O%y>>&oK+D2e6uWVX zoL~v3Z(i%$ZBFNw`95al%5~H9-2qpY*W%gBRP^-Z4CReYgT~yqv2cC@eNEK|U~rz+ zQ6sHc{gM(7WT(XQ1PtYzeQ3~=WW}00m+0+#@{5oxa&O2ZefY)d;3@R2^N~bv#E#as z{lmRyB1hvLQ~Cp}#q}*2IT^!YY@d0+UIl|R&=Ub*`IqET*mv=LKNQ^O&5Yy04*g1A zFo5j<7xWwdP;Ri$44MZ#TUd06V-3uEQx-cDFsf3e}9Jkz%E01_4@;^RGc+#-$8>M?S1yJ`Pyd)&1Ng(p# zKHt3{WzBtaat*%P@BIcG?PQGB9-T*9-m$jRSG!n=thr4`M<#Qz-t9Pr0&Gv%dX3Z% zpf;bI9`~w498ZL)l+V6ZMmORs$L0u|TdS(ph>@4t{%|KBM~|>;rh^2N%RSnnO|a`e z^sWrMcnt318vV4H`Ji0P?G|CR(!rx#Dx2jJuiX4}%sm(9{Ei?jByvES5&Ny@TupwBj@ZKo`R0gUSvpStbbEhw$*RkG(&Wojpw2Nxcu(!x?Dh7#DBXU+DV{-Jmp#{uuWWi7kFv($Z=D{X zRG`yiS$)40Xt7ZdRVX*lZ}T0iO;KQ1;E-@7G-2PzCGAf3QnRFAk1N)qsl@ocxiOYX zWao)Kf#}~gJP{_@;AqYm@1@#5aemlbUzsB6&F>dmm&I;!lDO` zl4dfH?3YZ4TW9y&D~#Zw90YxCWiGA7r%6R)x_L4CFpkpXU-5*=1UBBy!7lt7nSg2t zzL{*n`td_C3gh(h(r7YYFJYvwFRZ(-Z@fqa>3AiXEp-lW4FD*6@Yus&6*iSBmn@7n zlkV><7dS=iN=O_I0|;^v`P;2fJLp?O_rncQrPv^#8R_|av_0&5QKizAHaLoeXzW31bS>BU9mDY%Epg+W*-*A*Dlj1yF`o3qcV#>pN5bfDGC2*&Qp+;I$ zhINQ*Ld4kF?bQN}={PcRSCbZ~bBFgXI-R^giFl(of)C%GGzW-{I>*K&K7BH+8l^IQRoyBOoR_2iw)lQk6cR_SI# zJb!`L;^OyFpwS|M^9l9<963SfF_`D@8t(1MRZCi7t~!B5Zd(C16|PtLO+YQb#hh#q zd*6@kv59kw8(m-{rDx6dY5-JtMXwAAPu{>+PMHLhM2@|98m9GBb3k!BJ5p z6cpb=2PNR(!)9Bp$QN7=CeP)@?3^ErO9d~rJiZlz(wV)<_R>Ek|C-0^UK%QdVBfKy z6BT8LUUbpn6Brseey1O!Da98^QIhWoE245eEn{cg+SO53utmOID(CHdWR7u7V< zITZNv1mWdNu9D$g;)lPEG3V;s5GIiz!m5Y8`Ev4%s(J`z-j5V0>Mh?m&<|zTn}@od zZkQx7{)57b=HH=IP{rt%=|H`p2Q8l*rfB7R3%S?JWH6JDzIzg8>gG_d;OHLTWN4D! zJm=`AJdUbXN+7$I=nZoN1L0(69D%p4y#A{vOy~Pk;R?U0oHduRTf}`#-uy6aGb<$EcN9cxKMuQBUy=0&4sO#QiT^=(2#Zsn z0?1^GwW}h33c|?C$@K$8ds)u0mYCzs2=WOrq>PzBQ4r>{4A(otSblE<=oe-NZlV*?Cuw@2M?UJJr1p)?jIV?1|o7p`CnAhsnOa z#gf~<3MfHSU29HPUK)zc%=s5{KBI1uoMq}$`XeD#XS`oOd` znK%9cf&_q6!+^{wDJhNmBDFxOH0bjm$Scgwr?JnS#ekgLZDk~_FA}eb0rPFOgylfM zY5d9E{;}My<8;!rKI24=Lm#%DIa{*0jEw&FsG=ra{PiVWDtD#fu088hsAjR>e4&yg z6VsJ~yu5^c@(1NoO`xTLLq(f0dPds^HmVQ09Zf~baDV#nU_Mslc$s(S+i%3Mp3dcP zui?}tP~L=aGFu5H1x2w_96lCS$F~mX;Ly-+K!C0Ta90O&`(FGNMh_-2nB?R>q@tN=s=iUJDcG~YK?y*U=6qH~iHS*Mu=88oolR_dy}z7W zlq%#!;;A+|z5?)3=yKC>Cg3!-u+|h7?(K$)kZ3hI8ut#*0ScbEuAeId3Emn>ntDCi zA8hNKle=cC$lvXKeZ(syBr;j(_BHTprQv`*lt0wIX5Pt(E#mfem5D42==S!N)RQy1 z@%d@GnzJ(^9#?f4ay}7J2T+EPS65fww&%r1Dlpr9i#r?j?bkbdhjVjj6g)KHhOB0h z5f(DCP@w)qK|`~-+93!!Sa5kRM+HZQuIp|Q;k^(Z{RzW7SO)-^P0l$L)T|L~10^pw zJUP|sysDnI~i)!i#pWiqC%ub*l5{Z|4IOl*Nwmb(pEqQC!s{E$FLH&{TB*;d_nxfz7Zm4j#;UBW57Fl_>weS$ zXzufYf&$kax!iVr%9tIta77|;Ma0Ay(8B`pmztPNMm@FfR`#=VbD3>FuBe}Crkj;rZI+jddEbrPto)6`B#8uM&_MuwbiI8GEI&Qu?lS!BiOzoT)zqgMcQ4 zRBji;JN7CH7YuvvLgS>*skZrr=}R8&+6R~>zTCWI7~HKOKC^Z*`iuF=UOViz#jA`%kZ zz*Gk8h-#~aBqYB3AGKC7EfX(c=IaeFUejUmc0%Scbi5U|*|?`SHR2=j7JxN|GN)+^ zd2jg51C9kS@NOqaF)d{gc+8=7%W0jZS_PU;U?ZUAB3wCycCONCVVv;HV79zNNL2W< zre=7DZgEwvL#DG;%E&z)5q80>j0pJJ`5b5U_8U2Wjo1*9oNp~r9;;{oM#V$k)nDSt& zvxSC5%{Wq}%Gh!N?*3j4TsGvB_Cx@9t8h%lfHdC5DRX@58Meeh339XDCfUYtG-_ox zNPj$?S_hhnOfho4)%O?*PWew;lu0zQDv>A=xQyY=&0U@kBX0qC88D)mHY?gR8dtnO zfBvktiW&aFjLTzO7hmOhD-lPpBW`H;lH@B=hbcq3+Ys9^%R=q(W?Zt3?!dYci^cSh zloXywT*`vWCDl4_phxE*Q#fqvEe_YW2Z$^m;qLZTP~nr}CNaWfe!dtVA-K_R%5)sMnxeB1|e>> zP)-0T?3WJR)#U+~=>)P59J3l42ncTqrnZ%|wIde}w@T`kxwD{^<>UxOvc?xCG2UZK z=?Nf@B(eT9i+Q=6eD*>nFD4;j2b(q4!25^`UqM}6LQJf@F8z0(J^-*i9h{}lewfb| zhw`{qzQ#ibx;wld$Qqpw6{-8VoTZ3(h!-_*F3zidR~k9Q(P?xfvF=mS&~zGdEu-i$ zV6O%kEBkkR97|gQOvgAqRbPmDt>tJkdHAY!l{2qFU%38U<*~Tg3VJfF?}7~^wXPY| z(IMdZa2bw06cQHEVae#Q+AaV(J439}+b{<1)h3a{LxhD~9p^dOzZVw|vE&)qIpOuV z`rW2uGhb__Wsxz-*udGqVwSXe=+7U!vmKbhv*Uup562e5-aOSZLb6Y%d41G7br$L#buz()h>Y-d+d zEo1J~yk*Rw%Ya#~UUIRse7OmJ#M*ZqzB=UIU8uu&eDnqYb0)n`%>^sh4p*_#E8dLOHN(Xn8?jX7Y78YAkWLox658GRL8Op->&n##bjjY z;4$d*CUQ$eEo``VR?3jrk`eg%`C$+a#zs^7>Kx?diLcJ=y?NFkw#Axx)O`b++ZewZ zBt<>FyiNg0RtS0=5A*^N!P)eJLNi#a$r{?stSOP(MW6(Hqh1n@#T*JmccM0>@5Jj$ zQwK^n&e?62MaHtS!lDrLxngT9W+qxZX1Fw{K=$?yr`Ok6KsQKMnvZ&z%{(4y z(*;VytT}K5HDcmg`?y1|6SSIsn@*4=0`X`$;G6xRAycO4npMVlS)vFgXS^- zEm$|IG~^E{p`mc-G^)dB@v_~PY!!fF3`Sltx+m||9&S!+*mN2)0nuL^7X)>CRHOgb zPw3kRt-3YG#@Pykc$WaMEEtT}3%tK^yvc3HL6yMl@&afB1KLl1ipRXPZn`7`B3>MJ z>rzIlOUs#Y4~CUWz{B+(TQ?$B%?;ODanIUU!#EY5)mhGc>AJneDeQ3>?sqE^84g!A#Ju=OXoxtr z&v17<0m5=``7R#qQia$J!(1QkFd$d4n@Oz$LbTZ?7Xl!aIPs>JvE-tsr0g+eao3=d z`4L?a6}$4(9=s+9Sik3Z(h4FoUAiD=G4Bt{Y}cTfopW4zxl}q7nObmhxDeLejSe`F z(yBKu4|mcRJDNoYQe|?EHWZ-dqI2Uc-U! zV8AgTJ9V~rULSLRj64EU+iO$Gftx*i_C)7jV|<&~eU8tT>IF8TCN>uS*LU&$iS7Qg z+2OyA?Wvu+%G}+HJcIMSx(vSC2l$=N+R#&Adwn*I>L8$#RsaCZ>orFK)EO<(zW9;t zkmwn820l>Xf&tX|FsJ9`%dh!!Dgdy}3mB}Ay05Q(uLHAV(GYRLMlXYe&16G@#ahsD z(F3!Z!w2C+AK(>zGw*SMh6A9Vx3B;}r(22>zXpgJFeOtCj&bgTHNOoRpE)qS2#&N7 z(Y3`y4~yyqP+IS)cQvY>KuZD%SF2h?F_*>`ywVLo$J4XqX5q`5u+Sp>ha$OW0N%gP ze+Zo2`B~<^iLG{C7| zMbCFCstyt!%fkIBqCW>Oi!7^9h8#*czl&^yi+wnOJnhYp5dZ!Lb(!#O&ZkpOEtH!g ztx{%20gNHhes?`eCucCf!3c4Oo@#V}=?x_@Az&JTUEeNj2k0uC3P4S_To(oI$_|kL zZ?aCND=KMWYN92;U+HU{ll63^b=oY%V^T-TVXdHfK!#3kVDv^;4qG+?xj*<-%CN5@ z26yjJ5bG{A)psSWn{uLpT;zBJ!qR^>FXgD(yXf+z$e0}u+#Ki#3s1CS9^TF>w?!7P zz(x(g0iuyP<`0#Ni6Txp>mz?_U%%sexc2ost3|P8 z!Fer$!pC3Q;WN~SxhNxX$LCw{0mnoUr_j^C+?b}r1~S8{Jcl-YzX`6mQJB7kNnt!> z8<_5GtT&74Nj@oRmC_vLF|R5(su%SZA& z)8F>2>K}Q-ufFUph{R#6g-!7n(tI||6fj5DyrPe{A`ZX~Ti9MXKmbr| z-eNm-*Sa+H+0_e&%S`qD>#wy>RPLQeIkc}%;(j={MYI!We@+MuX357k*WwX{2-150 zaBj)DWA#TaOqrr~ab-u7hJ5Mp<)lYQU#!W~%I-Miac71@id)1}WFb&&DZb}*4JV^Y zLTa}Pdyy4g==(bS>OO{U2rK!^m|raB;VY2pHBINZrEeYCUQEj?|EBj7(Sn#mVfkn9 zMN?89m1l}9yIw4_g*MS(Ms-_Q_Fm0zpB-Q^4oVOwzP(KOY<0508WS3zt#})>c7;@= zZ9L(f5a!+ey{e=!rJ#xu|B(ehOvi~6$*NsW&6!8nAIHvcHS5Oa5%YYFUFmFR4xCH}t4x!PSPhqC2o0PMyhm6*;3zwHRbIlAQNuw{R~T=EM~Q z4FV4s6j)9oSlnrPp34`6?+?%MLt*VVXvAKAU8_~D}0o&&+ZX#K5>W}*3X(nBZ1c8>gbHc~5=Bx8N*9cf6vaM>Em zZIb7S>OCO$%xVbU&5=fA#ro^GltVzZ*F&YC{E>l!T9hp4_y4u_l~HkR!I}gDBxr!( zmOy~u?%j|O2=49Yaj&I#vK}W8iKn^aCe)NJMX=_=FQAn^JD&X@0PVs zo!V7jeI=)Yjen)4%Sb*WV))?@(1%hS+Qc9xxDtpygZsgA>ao@%V?{a6hot*(CI#b7 zrZoE(HNuyKA^fPMlOU$dX zo*EnX#f%ULZrH&8vlc+E_q36%*J2jYQdv2Cx0F2CJ>K5pK!~slFqx(0pu`LLFd7@g zPJ_de8GvQG)QErCWGT zU%|GQ)hs2R{YE{%fYR{E7=(_Qbn8O&`QujJJA}m^o%4*PnSm=qE;pHOzXnaBKhd+8 zg@IlnID_`kjnR2f5Gi3lkN@YjmUVCcwc2<-OBRM)*!fg5U+zHIq=Hfql| zyOgk^8Op1U{*`$=YKnt-KI#B7uhCf$?#Ja{*=0eyehoALyqvhhQE~7DJ1URn8kSqo zuj^*?ZWx*cps1y=z6Mtv$AeY>WYaH(f+J8)-*6!O1(tuC;_U?aeiTZB@`9G~w z|Ey(;qwi3Hg*Z%4ii)r8KrStQY3L6w1R4V?6OT4GpV;gckMd6g1a>&lL`PJ0^~A-) z#lz|n55ayyPL{B!rW1ttr0ulAK3Tli=E`CmGkI5NEdz9f%m3bw^!9?mCL$tKY8!j} zfZt$f;81Qogfx(R*kQIIRZbJ;4!Is4i!^`@20-*4fl!KNg0FgRa#5V2@?0De|1 zSRI@PiWMahi$$xRDQ6DMg!%Qy5C$G%`gwGIu$^v-@aXZA%sAMuyQ#>vT_}g7^Xq@` z{z$~$a*euTtU%RVE4h1eufRlBL&jL2Z5BFg8}e4I3IZc?YjPb=TG@XITJ0Qn3c}+9Cx-e(53A$H(_s z0&rzY1OJ+UUZJy=dhFpAt|&GSoZrIAK=Yi=SL7t zdxseO)!nIs1sA)&;GFy3TGy0lo|vAtwFXRWnd_1v@3?Q>u(x+`75EB1)q&aF`gV4% zd4Jr*U&i2zkHB5u!&`T4Bg&Wwg3@t}aL$&T2kz(flUQg5!Kk^pln-$Gv(Y z9~~FX_Z~x%frNb@?M7o^2}P+vOq2@5u(p%612^^+ ze+w%CLb^HZMIbgpNRNxP;gQ<}DC#yUGD1ieoI1mF%#++#aO!pPbkA4nheCMKl}hD@ zCnZ`U!F1d`qs#MTuRA(ApjY?w_K@1?lGB?ZVZl5Vid%fu>E=tM#!ISKWAXBUj(di$ z+yEex@!5DM3gca~HSHl*z>nQIJsCjL|9IcWfA_O{C5q5_*WGq7wz^)6%IsKQ;bqqg z9xu|5zi}%%y(zo(+FR5;iz2`il#LH%Tarxo$q2l3UE2R&dXBD=baP7G^w?Kr zQr}_#gFJ#x$cC}^I@WQ6myd5k4VzLJF#aF|>9xurWtjOAjqrKWyd6ck>VXO~a2CUy z3TJXs*CIkgUn2iI*5tn|N;EfNel9MHMs-DKXxtCADzu8CI@H1mHzY$fbGuh~c#L?y z%JJn5IMC5132#$$-Blsb78JtkciERvGg}DQsb}9~Q)XQd*VFh@gm8?BdfIg8>=aej z+!Ux^6hP(ej`)J6D|<~ z=5mJO&V;J#I3l~qBLB9sUwR%rE%ED<^=J;)r;cw*k;g#RpP4iz#IvPbs(#`TF_&WA zu0ldz@4z4m_k!Uk1}$Euqi)8Ap!k#*HEwJd%|&Hq2PkmGXrRs1QbdJS<4!sL7&;aQ z><}>3^6Mw;QN-{^jh`vkRNkvQ%cYC>4qa$hG^?#;RNPYXs!y0{X!2gz2RrQ<@%m|1 z#+1=L1etCj?@8-o^p3`2PSOa4q=?GNwvK&qn=50!(*a zv`lW;(pJ|#qANC4-rWL?3MNbf-ORk=5nKiBhHa_fJuTE8fh^ND4!w7kqd*)z$MPsj&GzMCc7Y7KN+ab_LEfp2eS`YtkwRDM#i$wKs=qz=8W zuanuEt9}CODJfx~q3H^rTC-Rx#Rhizb!f9U!+sM_Thlern&=2*QI^d{Kp+Y1Umcjv zqf*Q~vEG>$7Zx_);-~lk*AmpoC$dh2d5I^@?kPZ5q60C105Ms3`8tY^W3Z%2rSJ!_ zbMZ!hOa>*$-VV5q22c67SvKX!1Q6J%+$GbKTA_!AhU4^A7!`aXvih0QbGLAS#lY;z z2&lf)aYB4__yVcFingXFVPUf93T~vM0Cas5XyXD71{QEXC~z3O6b;kgB>!I3Lt$C$P30%1@g`<` zUz!bISW(=x(GWojgBFR-xb2=VM+c)3;#|w`ai8Pq6S)*lbjvSee)Uu#q+ zPOBX(dik_WkFS8-7T@t=1%*0V_Llu#gPWgSIeZ8fq{LbDyLJ+)sfSjb$r(`J)5Yc@ zo-UW)`keMQ*Q%VhlLx*dKHklOudiZ~JIzSQPuICIprm_7rt8l->DJExWj_tFJTLTAQ^68-)BfqjoT`MaB2LoDwHJ8QL) z!OINDFJC=DG|)9!08D52H0V~fc5>w!WdcDimFp