├── .editorconfig ├── .eslintrc.cjs ├── .github ├── dependabot.yml └── workflows │ ├── deploy-ccd-js-gen.yml │ ├── deploy-react-components.yml │ ├── deploy-rust-bindings.yml │ ├── deploy-sdk.yml │ ├── deploy-wallet-connectors.yml │ └── pipeline.yml ├── .gitignore ├── .gitmodules ├── .markdown-linkcheck.json ├── .markdownlint.yaml ├── .npmrc ├── .prettierignore ├── .prettierrc ├── .yarn ├── plugins │ └── @yarnpkg │ │ └── plugin-workspace-tools.cjs └── releases │ └── yarn-berry.cjs ├── .yarnrc.yml ├── LICENSE ├── README.md ├── docs ├── README.md ├── package.json ├── pages │ ├── cis2-contracts.md │ ├── documentation.md │ ├── identity-proofs.md │ ├── misc-pages │ │ ├── account-creation.md │ │ ├── bundler-optimizations.md │ │ ├── grpc-migration.md │ │ ├── grpc-v1.md │ │ ├── react-native.md │ │ └── upgrade-guide.md │ ├── runnable-examples.md │ ├── transactions.md │ └── utility-functions.md ├── tsconfig.json └── typedoc.config.cjs ├── examples ├── nodejs │ ├── README.md │ ├── cis2 │ │ ├── balanceOf.ts │ │ ├── dryRun.transfer.ts │ │ ├── dryRun.updateOperator.ts │ │ ├── operatorOf.ts │ │ ├── tokenMetadata.ts │ │ ├── transfer.ts │ │ └── updateOperator.ts │ ├── cis4 │ │ ├── credentialEntry.ts │ │ ├── credentialStatus.ts │ │ ├── issuer.ts │ │ ├── registerCredential.ts │ │ ├── registerRevocationKeys.ts │ │ ├── registryMetadata.ts │ │ ├── removeRevocationKeys.ts │ │ ├── revocationKeys.ts │ │ ├── revokeCredentialAsHolder.ts │ │ ├── revokeCredentialAsIssuer.ts │ │ └── revokeCredentialAsOther.ts │ ├── client │ │ ├── banPeer.ts │ │ ├── dumpStart.ts │ │ ├── dumpStop.ts │ │ ├── findFirstFinalizedBlockNoLaterThan.ts │ │ ├── findFirstNonGenesisAccount.ts │ │ ├── findInstanceCreation.ts │ │ ├── getAccountInfo.ts │ │ ├── getAccountList.ts │ │ ├── getAccountNonFinalizedTransactions.ts │ │ ├── getAncestors.ts │ │ ├── getAnonymityRevokers.ts │ │ ├── getBakerList.ts │ │ ├── getBannedPeers.ts │ │ ├── getBlockChainParameters.ts │ │ ├── getBlockFinalizationSummary.ts │ │ ├── getBlockInfo.ts │ │ ├── getBlockItemStatus.ts │ │ ├── getBlockPendingUpdates.ts │ │ ├── getBlockSpecialEvents.ts │ │ ├── getBlockTransactionEvents.ts │ │ ├── getBlocks.ts │ │ ├── getBlocksAbort.ts │ │ ├── getBlocksAtHeightAbsolute.ts │ │ ├── getBlocksAtHeightRelative.ts │ │ ├── getBranches.ts │ │ ├── getConsensusStatus.ts │ │ ├── getCryptographicParameters.ts │ │ ├── getElectionInfo.ts │ │ ├── getEmbeddedSchema.ts │ │ ├── getFinalizedBlocks.ts │ │ ├── getFinalizedBlocksFrom.ts │ │ ├── getIdentityProviders.ts │ │ ├── getInstanceInfo.ts │ │ ├── getInstanceState.ts │ │ ├── getModuleList.ts │ │ ├── getModuleSource.ts │ │ ├── getNextAccountSequenceNumber.ts │ │ ├── getNextUpdateSequenceNumbers.ts │ │ ├── getNodeInfo.ts │ │ ├── getPassiveDelegationInfo.ts │ │ ├── getPassiveDelegators.ts │ │ ├── getPassiveDelegatorsPendingChanges.ts │ │ ├── getPassiveDelegatorsRewardPeriod.ts │ │ ├── getPeersInfo.ts │ │ ├── getPoolDelegators.ts │ │ ├── getPoolDelegatorsRewardPeriod.ts │ │ ├── getPoolInfo.ts │ │ ├── getTokenomicsInfo.ts │ │ ├── healthCheck.ts │ │ ├── instanceStateLookup.ts │ │ ├── invokeContract.ts │ │ ├── peerConnect.ts │ │ ├── peerDisconnect.ts │ │ ├── shutdown.ts │ │ └── unbanPeer.ts │ ├── common │ │ ├── aliases.ts │ │ ├── bakerAdd.ts │ │ ├── bakerRemove.ts │ │ ├── buildAccountSigner.ts │ │ ├── cis0Supports.ts │ │ ├── delegationAdd.ts │ │ ├── delegationRemove.ts │ │ ├── deployModule.ts │ │ ├── simpleTransfer.ts │ │ ├── statements.ts │ │ └── streamToList.ts │ ├── composed-examples │ │ ├── findAccountCreationBlock.ts │ │ ├── getEmbeddedSchemaFromInstance.ts │ │ ├── initAndUpdateContract.ts │ │ ├── listAccountCreation.ts │ │ ├── listInitialAccounts.ts │ │ └── listNumberAccountTransactions.ts │ ├── package.json │ ├── shared │ │ └── util.ts │ ├── shims │ │ └── ed25519.node.ts │ ├── tsconfig.eslint.json │ ├── tsconfig.json │ └── wCCD │ │ ├── client-error-message.ts │ │ ├── client-events.ts │ │ ├── client-tokenMetadata.ts │ │ └── generate.ts ├── reactnative │ ├── .bundle │ │ └── config │ ├── .gitignore │ ├── .watchmanconfig │ ├── App.tsx │ ├── Gemfile │ ├── Gemfile.lock │ ├── README.md │ ├── __tests__ │ │ └── App.test.tsx │ ├── android │ │ ├── app │ │ │ ├── build.gradle │ │ │ ├── debug.keystore │ │ │ ├── proguard-rules.pro │ │ │ └── src │ │ │ │ ├── debug │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── reactnative │ │ │ │ │ └── ReactNativeFlipper.java │ │ │ │ ├── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── reactnative │ │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ │ └── MainApplication.java │ │ │ │ └── res │ │ │ │ │ ├── drawable │ │ │ │ │ └── rn_edit_text_material.xml │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ └── values │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── styles.xml │ │ │ │ └── release │ │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── reactnative │ │ │ │ └── ReactNativeFlipper.java │ │ ├── build.gradle │ │ ├── gradle.properties │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle │ ├── app.json │ ├── babel.config.js │ ├── index.js │ ├── ios │ │ ├── .xcode.env │ │ ├── Podfile │ │ ├── Podfile.lock │ │ ├── reactnative.xcodeproj │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace │ │ │ │ └── xcshareddata │ │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ │ └── WorkspaceSettings.xcsettings │ │ │ └── xcshareddata │ │ │ │ └── xcschemes │ │ │ │ └── reactnative.xcscheme │ │ ├── reactnative.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── WorkspaceSettings.xcsettings │ │ ├── reactnative │ │ │ ├── AppDelegate.h │ │ │ ├── AppDelegate.mm │ │ │ ├── Images.xcassets │ │ │ │ ├── AppIcon.appiconset │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ ├── Info.plist │ │ │ ├── LaunchScreen.storyboard │ │ │ └── main.m │ │ └── reactnativeTests │ │ │ ├── Info.plist │ │ │ └── reactnativeTests.m │ ├── jest.config.js │ ├── jest │ │ └── setup.ts │ ├── metro.config.js │ ├── package.json │ ├── polyfill.ts │ ├── tsconfig.eslint.json │ └── tsconfig.json ├── wallet-connection │ ├── contractupdate │ │ ├── .dockerignore │ │ ├── .gitignore │ │ ├── Dockerfile │ │ ├── README.md │ │ ├── docker-compose.yaml │ │ ├── package.json │ │ ├── public │ │ │ ├── favicon.ico │ │ │ ├── index.html │ │ │ ├── logo192.png │ │ │ ├── logo512.png │ │ │ ├── manifest.json │ │ │ └── robots.txt │ │ ├── src │ │ │ ├── App.tsx │ │ │ ├── ConnectedAccount.tsx │ │ │ ├── ContractDetails.tsx │ │ │ ├── ContractInvoker.tsx │ │ │ ├── NetworkSelector.tsx │ │ │ ├── Root.tsx │ │ │ ├── WalletConnectorButton.tsx │ │ │ ├── config.ts │ │ │ ├── index.tsx │ │ │ ├── react-app-env.d.ts │ │ │ ├── reportWebVitals.ts │ │ │ └── util.ts │ │ └── tsconfig.json │ ├── proofs │ │ ├── .gitignore │ │ ├── .prettierignore │ │ ├── package.json │ │ ├── public │ │ │ ├── favicon.ico │ │ │ ├── index.html │ │ │ ├── logo192.png │ │ │ ├── logo512.png │ │ │ ├── manifest.json │ │ │ └── robots.txt │ │ ├── src │ │ │ ├── App.tsx │ │ │ ├── WalletConnectorButton.tsx │ │ │ ├── config.ts │ │ │ └── index.tsx │ │ └── tsconfig.json │ └── sign-message │ │ ├── .gitignore │ │ ├── .prettierignore │ │ ├── package.json │ │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ └── robots.txt │ │ ├── src │ │ ├── App.tsx │ │ ├── WalletConnectorButton.tsx │ │ ├── config.ts │ │ ├── index.tsx │ │ └── util.ts │ │ └── tsconfig.json └── wallet │ ├── README.md │ ├── index.html │ ├── package.json │ ├── src │ ├── Account.tsx │ ├── ConfirmIdentity.tsx │ ├── CreateAccount.tsx │ ├── CreateIdentity.tsx │ ├── Identity.tsx │ ├── Index.tsx │ ├── NewIdentity.tsx │ ├── RecoverIdentity.tsx │ ├── Setup.tsx │ ├── account-worker.ts │ ├── constants.ts │ ├── identity-worker.ts │ ├── index.css │ ├── recovery-worker.ts │ ├── types.ts │ └── util.ts │ ├── tsconfig.eslint.json │ ├── tsconfig.json │ └── vite.config.ts ├── package.json ├── packages ├── ccd-js-gen │ ├── CHANGELOG.md │ ├── README.md │ ├── bin │ │ └── ccd-js-gen.js │ ├── jest.config.ts │ ├── package.json │ ├── src │ │ ├── cli.ts │ │ └── lib.ts │ ├── test │ │ ├── generate-test-bench.test.ts │ │ ├── generate-wCCD.test.ts │ │ ├── resources │ │ │ ├── test-bench.wasm.v1 │ │ │ └── wCCD.wasm.v1 │ │ └── testHelpers.ts │ ├── tsconfig.build.json │ ├── tsconfig.eslint.json │ └── tsconfig.json ├── react-components │ ├── .gitignore │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── WithWalletConnector.ts │ │ ├── error.ts │ │ ├── index.ts │ │ ├── useConnect.ts │ │ ├── useConnection.ts │ │ ├── useContractSelector.ts │ │ ├── useGrpcClient.ts │ │ ├── useModuleSchemaRpc.ts │ │ └── useWalletConnectorSelector.ts │ └── tsconfig.json ├── rust-bindings │ ├── CHANGELOG.md │ ├── Cargo.lock │ ├── Cargo.toml │ ├── README.md │ ├── package.json │ ├── packages │ │ ├── common │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ ├── helpers.rs │ │ │ │ ├── lib.rs │ │ │ │ └── types.rs │ │ ├── dapp │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ ├── aux_functions.rs │ │ │ │ ├── external_functions.rs │ │ │ │ └── lib.rs │ │ └── wallet │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ ├── aux_functions.rs │ │ │ ├── external_functions.rs │ │ │ └── lib.rs │ ├── scripts │ │ ├── build-react-native-dapp.ts │ │ ├── build-react-native-wallet.ts │ │ └── build-scripts.ts │ ├── ts-src │ │ ├── dapp.ts │ │ └── wallet.ts │ ├── tsconfig.build.json │ ├── tsconfig.json │ └── webpack.config.ts ├── sdk │ ├── .size-limit.ts │ ├── CHANGELOG.md │ ├── README.md │ ├── babel.config.cjs │ ├── jest.config.react-native.ts │ ├── jest.config.ts │ ├── jest.config.web.ts │ ├── package.json │ ├── scripts │ │ └── proto-node-esm-compat.js │ ├── src │ │ ├── GenericContract.ts │ │ ├── accountHelpers.ts │ │ ├── accountTransactions.ts │ │ ├── cis0.ts │ │ ├── cis2 │ │ │ ├── CIS2Contract.ts │ │ │ ├── index.ts │ │ │ └── util.ts │ │ ├── cis3 │ │ │ ├── CIS3Contract.ts │ │ │ ├── index.ts │ │ │ └── util.ts │ │ ├── cis4 │ │ │ ├── CIS4Contract.ts │ │ │ ├── index.ts │ │ │ └── util.ts │ │ ├── commonProofTypes.ts │ │ ├── constants.ts │ │ ├── contractHelpers.ts │ │ ├── deserialization.ts │ │ ├── deserializationHelpers.ts │ │ ├── energyCost.ts │ │ ├── grpc │ │ │ ├── GRPCClient.ts │ │ │ ├── index.ts │ │ │ └── translation.ts │ │ ├── hash.ts │ │ ├── id │ │ │ ├── idProofTypes.ts │ │ │ ├── idProofs.ts │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── nodejs │ │ │ ├── grpc.ts │ │ │ ├── index.ts │ │ │ ├── util.ts │ │ │ └── wallet │ │ │ │ ├── crypto.ts │ │ │ │ └── types.ts │ │ ├── overwrites.d.ts │ │ ├── pub │ │ │ ├── cis0.ts │ │ │ ├── cis2.ts │ │ │ ├── cis3.ts │ │ │ ├── cis4.ts │ │ │ ├── grpc.ts │ │ │ ├── id.ts │ │ │ ├── nodejs.ts │ │ │ ├── schema.ts │ │ │ ├── types.ts │ │ │ ├── util.ts │ │ │ ├── wasm.ts │ │ │ └── web3-id.ts │ │ ├── ratioHelpers.ts │ │ ├── schema.ts │ │ ├── schemaTypes.ts │ │ ├── serialization.ts │ │ ├── serializationHelpers.ts │ │ ├── shims │ │ │ └── ed25519 │ │ │ │ ├── default.ts │ │ │ │ ├── node.ts │ │ │ │ └── react-native.ts │ │ ├── signHelpers.ts │ │ ├── types.ts │ │ ├── types │ │ │ ├── AccountAddress.ts │ │ │ ├── BlockHash.ts │ │ │ ├── BlockSpecialEvents.ts │ │ │ ├── CcdAmount.ts │ │ │ ├── ContractAddress.ts │ │ │ ├── ContractEvent.ts │ │ │ ├── ContractName.ts │ │ │ ├── CredentialRegistrationId.ts │ │ │ ├── DataBlob.ts │ │ │ ├── Duration.ts │ │ │ ├── Energy.ts │ │ │ ├── EntrypointName.ts │ │ │ ├── InitName.ts │ │ │ ├── ModuleClient.ts │ │ │ ├── ModuleReference.ts │ │ │ ├── NodeInfo.ts │ │ │ ├── Parameter.ts │ │ │ ├── PeerInfo.ts │ │ │ ├── ReceiveName.ts │ │ │ ├── ReturnValue.ts │ │ │ ├── SequenceNumber.ts │ │ │ ├── Timestamp.ts │ │ │ ├── TransactionExpiry.ts │ │ │ ├── TransactionHash.ts │ │ │ ├── VerifiablePresentation.ts │ │ │ ├── VersionedModuleSource.ts │ │ │ ├── blockItemSummary.ts │ │ │ ├── chainUpdate.ts │ │ │ ├── errors.ts │ │ │ ├── json.ts │ │ │ ├── rejectReason.ts │ │ │ ├── transactionEvent.ts │ │ │ └── util.ts │ │ ├── uleb128.ts │ │ ├── util.ts │ │ ├── versionedTypeHelpers.ts │ │ ├── wasm │ │ │ ├── HdWallet.ts │ │ │ ├── accountHelpers.ts │ │ │ ├── credentialDeploymentTransactions.ts │ │ │ ├── deserialization.ts │ │ │ ├── identity.ts │ │ │ ├── index.ts │ │ │ ├── serialization.ts │ │ │ └── web3Id.ts │ │ └── web3-id │ │ │ ├── grpc.ts │ │ │ ├── helpers.ts │ │ │ ├── index.ts │ │ │ ├── proofs.ts │ │ │ └── types.ts │ ├── test │ │ ├── ci │ │ │ ├── HdWallet.test.ts │ │ │ ├── VerifiablePresentation.test.ts │ │ │ ├── accountHelpers.test.ts │ │ │ ├── accountTransactions.test.ts │ │ │ ├── alias.test.ts │ │ │ ├── credentialDeployment.test.ts │ │ │ ├── deserialization.test.ts │ │ │ ├── id.test.ts │ │ │ ├── idProofs.test.ts │ │ │ ├── module-schema.test.ts │ │ │ ├── resources │ │ │ │ ├── ars_infos.json │ │ │ │ ├── auction-with-errors-schema.bin │ │ │ │ ├── cdi.json │ │ │ │ ├── cdt.json │ │ │ │ ├── cis1-wccd-schema-v0-versioned.bin │ │ │ │ ├── cis2-nft-schema.bin │ │ │ │ ├── cis2-wccd-schema-v1-versioned.bin │ │ │ │ ├── credential-input-no-seed.json │ │ │ │ ├── expectedPresentation.ts │ │ │ │ ├── expectedStatements.ts │ │ │ │ ├── global.json │ │ │ │ ├── icecream-schema.bin │ │ │ │ ├── icecream-with-schema.wasm │ │ │ │ ├── identity-object.json │ │ │ │ ├── idv0.json │ │ │ │ ├── ip_info.json │ │ │ │ ├── schema.ts │ │ │ │ └── two-step-transfer-schema.bin │ │ │ ├── schema.test.ts │ │ │ ├── serialization.test.ts │ │ │ ├── signHelpers.test.ts │ │ │ ├── types.test.ts │ │ │ ├── types │ │ │ │ ├── AccountAddress.test.ts │ │ │ │ ├── Duration.test.ts │ │ │ │ ├── blockItemSummary.test.ts │ │ │ │ ├── blockSpecialEvents.test.ts │ │ │ │ ├── ccdAmount.test.ts │ │ │ │ └── json.test.ts │ │ │ ├── uleb128.test.ts │ │ │ ├── util.test.ts │ │ │ ├── web3IdHelpers.test.ts │ │ │ └── web3Proofs.test.ts │ │ ├── client │ │ │ ├── CIS2Contract.test.ts │ │ │ ├── CIS3Contract.test.ts │ │ │ ├── CIS4Contract.test.ts │ │ │ ├── cis0.test.ts │ │ │ ├── cis2Util.test.ts │ │ │ ├── cis3Util.test.ts │ │ │ ├── cis4Util.test.ts │ │ │ ├── clientV2.test.ts │ │ │ ├── deserialization.test.ts │ │ │ ├── events.test.ts │ │ │ ├── getConsensusStatus.test.ts │ │ │ ├── manualTests.test.ts │ │ │ ├── rejectReasons.test.ts │ │ │ ├── resources │ │ │ │ ├── bulletproofgenerators.ts │ │ │ │ ├── cis2-block-item-summary.bin │ │ │ │ ├── cis4-block-item-summary.bin │ │ │ │ ├── expectedJsons.ts │ │ │ │ ├── ipVerifyKeys.ts │ │ │ │ ├── mobileWalletExport.json │ │ │ │ ├── piggy_bank.wasm │ │ │ │ ├── schemaFiles │ │ │ │ │ ├── schema11.bin │ │ │ │ │ ├── schema12.bin │ │ │ │ │ ├── schema14.bin │ │ │ │ │ ├── schema15.bin │ │ │ │ │ ├── schema16.bin │ │ │ │ │ ├── schema17.bin │ │ │ │ │ ├── schema18.bin │ │ │ │ │ ├── schema21.bin │ │ │ │ │ ├── schema30.bin │ │ │ │ │ ├── schema31.bin │ │ │ │ │ ├── schema32.bin │ │ │ │ │ ├── schema33.bin │ │ │ │ │ ├── schema34.bin │ │ │ │ │ ├── schema35.bin │ │ │ │ │ ├── schema6.bin │ │ │ │ │ ├── schema8.bin │ │ │ │ │ ├── schema_test.bin │ │ │ │ │ └── schema_two_step_transfer.bin │ │ │ │ ├── smartcontracts │ │ │ │ │ ├── CAddress │ │ │ │ │ │ └── src │ │ │ │ │ │ │ └── lib.rs │ │ │ │ │ ├── ComplexEnum1 │ │ │ │ │ │ └── src │ │ │ │ │ │ │ └── lib.rs │ │ │ │ │ ├── ComplexEnum2 │ │ │ │ │ │ └── src │ │ │ │ │ │ │ └── lib.rs │ │ │ │ │ ├── ContractForDuration │ │ │ │ │ │ └── src │ │ │ │ │ │ │ └── lib.rs │ │ │ │ │ ├── ContractForTime │ │ │ │ │ │ └── src │ │ │ │ │ │ │ └── lib.rs │ │ │ │ │ ├── INDBank │ │ │ │ │ │ └── src │ │ │ │ │ │ │ └── lib.rs │ │ │ │ │ ├── INDBankBool1 │ │ │ │ │ │ └── src │ │ │ │ │ │ │ └── lib.rs │ │ │ │ │ ├── INDBankStringArray │ │ │ │ │ │ └── src │ │ │ │ │ │ │ └── lib.rs │ │ │ │ │ ├── INDBankU83 │ │ │ │ │ │ └── src │ │ │ │ │ │ │ └── lib.rs │ │ │ │ │ ├── ListContract │ │ │ │ │ │ └── src │ │ │ │ │ │ │ └── lib.rs │ │ │ │ │ ├── MarkSheet │ │ │ │ │ │ └── src │ │ │ │ │ │ │ └── lib.rs │ │ │ │ │ ├── SampleContract1 │ │ │ │ │ │ └── src │ │ │ │ │ │ │ └── lib.rs │ │ │ │ │ ├── SimpleEnum │ │ │ │ │ │ └── src │ │ │ │ │ │ │ └── lib.rs │ │ │ │ │ ├── SimpleU8 │ │ │ │ │ │ └── src │ │ │ │ │ │ │ └── lib.rs │ │ │ │ │ ├── UserAddress │ │ │ │ │ │ └── src │ │ │ │ │ │ │ └── lib.rs │ │ │ │ │ ├── UserAmount │ │ │ │ │ │ └── src │ │ │ │ │ │ │ └── lib.rs │ │ │ │ │ ├── UserDetails │ │ │ │ │ │ └── src │ │ │ │ │ │ │ └── lib.rs │ │ │ │ │ └── schema-test │ │ │ │ │ │ └── src │ │ │ │ │ │ └── lib.rs │ │ │ │ └── two-step-transfer-schema.bin │ │ │ ├── specialEvents.test.ts │ │ │ ├── testHelpers.ts │ │ │ └── web3id.test.ts │ │ ├── globals.ts │ │ └── setup.web.ts │ ├── tsconfig.build.json │ ├── tsconfig.json │ └── webpack.config.ts └── wallet-connectors │ ├── .gitignore │ ├── .prettierignore │ ├── CHANGELOG.md │ ├── README.md │ ├── jest.config.ts │ ├── package.json │ ├── src │ ├── BrowserWallet.ts │ ├── WalletConnect.ts │ ├── WalletConnection.ts │ ├── constants.ts │ ├── error.ts │ └── index.ts │ ├── test │ └── WalletConnection.test.ts │ ├── tsconfig.json │ └── tsconfig.test.json ├── rustfmt.toml ├── tsconfig-base.json ├── tsconfig.eslint.json ├── tsconfig.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 4 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | max_line_length = 120 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [*.{yml,yaml}] 16 | indent_size = 2 17 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: / 5 | schedule: 6 | interval: daily 7 | 8 | - package-ecosystem: npm 9 | directory: / 10 | schedule: 11 | interval: daily 12 | open-pull-requests-limit: 0 # disable non-security upgrades 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Yarn stuff 2 | .pnp.* 3 | .yarn/* 4 | !.yarn/patches 5 | !.yarn/plugins 6 | !.yarn/releases 7 | !.yarn/sdks 8 | !.yarn/versions 9 | yarn-error.log 10 | 11 | # Dependency directory 12 | node_modules 13 | 14 | # Eslint cache 15 | .eslintcache 16 | 17 | # Compiled files 18 | **/lib/**/* 19 | target 20 | dist 21 | doc 22 | !packages/rust-bindings/tools/binaryen/lib/**/* 23 | 24 | # Auto generate files from the gRPC proto file 25 | grpc-api 26 | 27 | # Webpack cache 28 | .webpack-cache 29 | 30 | # Generated documentation by typedoc 31 | typedoc 32 | 33 | # WASM files are generated with wasm-pack 34 | pkg 35 | 36 | # Manual testing files 37 | testing.ts 38 | testing.js 39 | 40 | # Package lock 41 | package-lock.json 42 | 43 | #tsc build files 44 | *.tsbuildinfo 45 | 46 | # MacOS 47 | .DS_Store 48 | 49 | .vscode 50 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "deps/concordium-base"] 2 | path = deps/concordium-base 3 | url = ../concordium-base.git 4 | -------------------------------------------------------------------------------- /.markdown-linkcheck.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignorePatterns": [ 3 | { 4 | "pattern": "classes/grpc.ConcordiumGRPCClient.html" 5 | } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | //registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN} 2 | registry=https://registry.npmjs.org/ 3 | always-auth=true 4 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .yarn 2 | 3 | *.md 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "singleQuote": true, 4 | "plugins": ["@trivago/prettier-plugin-sort-imports"], 5 | "importOrder": ["^~", "^[./]"], 6 | "importOrderSeparation": true, 7 | "importOrderSortSpecifiers": true 8 | } 9 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | 3 | plugins: 4 | - path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs 5 | spec: '@yarnpkg/plugin-workspace-tools' 6 | 7 | yarnPath: .yarn/releases/yarn-berry.cjs 8 | 9 | enableMessageNames: false 10 | 11 | # publishing 12 | npmPublishAccess: 'public' 13 | npmPublishRegistry: 'https://registry.npmjs.org' 14 | # npmAuthToken is set in CD pipeline 15 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # docs 2 | 3 | Holds documentation to be built into the documentation generated by typedoc. 4 | Currently, this needs to use its own version of typescript due to incompatibility 5 | with the version used in the rest of the workspace. 6 | 7 | ## Project structure 8 | 9 | Pages reside in the `./pages` folder, and should be included by adding 10 | a corresponding entry in `typedoc.json`. 11 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs", 3 | "packageManager": "yarn@3.2.1", 4 | "private": true, 5 | "scripts": { 6 | "build:docs": "typedoc" 7 | }, 8 | "devDependencies": { 9 | "@knodes/typedoc-plugin-code-blocks": "^0.23.0", 10 | "@knodes/typedoc-plugin-pages": "^0.23.0", 11 | "typedoc": "^0.23", 12 | "typedoc-plugin-merge-modules": "^4.0.1", 13 | "typedoc-plugin-missing-exports": "^0.23", 14 | "typescript": "5.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /docs/pages/misc-pages/react-native.md: -------------------------------------------------------------------------------- 1 | ## Using the SDK with react native 2 | 3 | To use the SDK in a react native context, it is required to include some polyfills for functionality used in the SDK. 4 | The list of polyfills to be installed in the project alongside `@concordium/web-sdk` include: 5 | 6 | ```json 7 | { 8 | ... 9 | "dependencies": { 10 | "@azure/core-asynciterator-polyfill": "...", 11 | "@stardazed/streams-polyfill": "...", 12 | "react-native-get-random-values": "...", 13 | "react-native-polyfill-globals": "...", 14 | "text-encoding": "..." 15 | } 16 | } 17 | ``` 18 | 19 | ### Installation 20 | 21 | ```bash 22 | yarn add @concordium/web-sdk react-native-polyfill-globals react-native-get-random-values text-encoding @azure/core-asynciterator-polyfill @stardazed/streams-polyfill # or npm install 23 | npx pod-install # if building for ios, adds native modules from dependencies to project. 24 | ``` 25 | 26 | ### Adding polyfill to app 27 | 28 | {@codeblock ~~:reactnative/polyfill.ts#documentation-snippet} 29 | 30 | {@codeblock ~~:reactnative/index.js#documentation-snippet} 31 | 32 | This ensures the native modules required by the SDK are present. 33 | 34 | ### Unsupported functionality 35 | 36 | Due to current lack of support for web assembly in react native, some aspects of the SDK are not supported on the platform. 37 | This is specifically scoped to the functionality exposed at the entrypoint `@concordium/web-sdk/wasm`. Everything else supported on web 38 | platforms should also be supported on react native. 39 | -------------------------------------------------------------------------------- /docs/pages/runnable-examples.md: -------------------------------------------------------------------------------- 1 | There is a collection of runnable examples that utilizes the SDK. These are 2 | located in the examples folder of the repo. To run an example call, navigate 3 | to the examples directory from the repo and run your example: 4 | 5 | ```shell 6 | yarn run-example /path/to/example.ts [opts] 7 | ``` 8 | 9 | Where opts are any arguments that the example script takes. 10 | 11 | Note that you must first build the project using: 12 | 13 | ```shell 14 | yarn build:dev 15 | ``` 16 | 17 | For example, after building, navigate to the `examples` directory from the 18 | repo root and run: 19 | 20 | ```shell 21 | yarn run-example client/getBlockInfo.ts 22 | ``` 23 | 24 | This will get block info on the last finalized block and print the 25 | information. The above command assumes that you have a _mainnet_ Concordium 26 | Node running on your machine with the GRPCv2 API exposed on port 20000 27 | (default). 28 | 29 | If you are running a testnet node where the GRPCv2 API is exposed by default 30 | on port 20001 you can override the GRPC-endpoint using the `--endpoint` flag: 31 | 32 | ```shell 33 | yarn run-example client/getBlockInfo.ts --endpoint localhost:20001 34 | ``` 35 | 36 | For information on how to run a Concordium node see [this 37 | page](https://developer.concordium.software/en/mainnet/net/nodes/node-requirements.html) 38 | -------------------------------------------------------------------------------- /docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "module": "NodeNext", 5 | "moduleResolution": "NodeNext" 6 | }, 7 | "include": [ 8 | "../packages/**/*", 9 | "./typedoc.config.cjs" 10 | ], 11 | "exclude": [ 12 | "../packages/ccd-js-gen/**/*" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /examples/nodejs/README.md: -------------------------------------------------------------------------------- 1 | ## Examples for the Concordium NodeJS-SDK 2 | 3 | This is a collection of scripts/examples that utilizes the SDK. There are 4 | three directories with examples: 5 | 6 | - `ccd-js-gen` containing examples with generate and using smart contract clients. 7 | - `client` containing examples that utilize the client to interact with 8 | a Concordium node. 9 | - `cis2` containing examples that helps interact with CIS-2 compliant smart contracts. 10 | - `cis4` containing examples that helps interact with CIS-4 compliant smart contracts. 11 | - `common` that use various general functions from the library. 12 | 13 | ### Building 14 | 15 | To try the examples you need to build the entire project, which can be time comsuming the first time: 16 | 17 | ```shell 18 | yarn build:dev 19 | ``` 20 | 21 | ### Skip building 22 | 23 | An alternative to building all of the packages in the project, you can change the code base to use the builds already published on NPM, note that this might not work for unreleased changes: 24 | 25 | - Remove packages from the workspace i.e remove the line with `"./packages/*",` from `package.json` in the project root. 26 | - Replace `workspace:^` in `package.json` found in this example with `*`: 27 | 28 | ```json 29 | ... 30 | "@concordium/ccd-js-gen": "*", 31 | "@concordium/web-sdk": "*", 32 | ``` 33 | 34 | Then run: 35 | 36 | ```shell 37 | yarn workspaces focus @concordium/examples 38 | ``` 39 | 40 | to only install dependencies related to examples. 41 | 42 | ### Run an example 43 | 44 | To run an example call: 45 | 46 | ```shell 47 | yarn run-example /path/to/example.ts [opts] 48 | ``` 49 | 50 | Where opts are any arguments that the example script takes. 51 | -------------------------------------------------------------------------------- /examples/nodejs/cis4/issuer.ts: -------------------------------------------------------------------------------- 1 | import { CIS4Contract, ContractAddress } from '@concordium/web-sdk'; 2 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 3 | import { credentials } from '@grpc/grpc-js'; 4 | import meow from 'meow'; 5 | 6 | import { parseEndpoint } from '../shared/util.js'; 7 | 8 | const cli = meow( 9 | ` 10 | Usage 11 | $ yarn run-example [options] 12 | 13 | Required 14 | --index, -i The index of the smart contract 15 | 16 | Options 17 | --help, -h Displays this message 18 | --endpoint, -e Specify endpoint of a grpc2 interface of a Concordium node in the format "address:port". Defaults to 'localhost:20000' 19 | --subindex, The subindex of the smart contract. Defaults to 0 20 | `, 21 | { 22 | importMeta: import.meta, 23 | flags: { 24 | endpoint: { 25 | type: 'string', 26 | alias: 'e', 27 | default: 'localhost:20000', 28 | }, 29 | index: { 30 | type: 'number', 31 | alias: 'i', 32 | isRequired: true, 33 | }, 34 | subindex: { 35 | type: 'number', 36 | default: 0, 37 | }, 38 | }, 39 | } 40 | ); 41 | 42 | const [address, port] = parseEndpoint(cli.flags.endpoint); 43 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 44 | 45 | (async () => { 46 | const contract = await CIS4Contract.create(client, ContractAddress.create(cli.flags.index, cli.flags.subindex)); 47 | 48 | const issuer = await contract.issuer(); 49 | console.log('Issuer public key:', issuer); 50 | })(); 51 | -------------------------------------------------------------------------------- /examples/nodejs/cis4/registryMetadata.ts: -------------------------------------------------------------------------------- 1 | import { CIS4Contract, ContractAddress } from '@concordium/web-sdk'; 2 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 3 | import { credentials } from '@grpc/grpc-js'; 4 | import meow from 'meow'; 5 | 6 | import { parseEndpoint } from '../shared/util.js'; 7 | 8 | const cli = meow( 9 | ` 10 | Usage 11 | $ yarn run-example [options] 12 | 13 | Required 14 | --index, -i The index of the smart contract 15 | 16 | Options 17 | --help, -h Displays this message 18 | --endpoint, -e Specify endpoint of a grpc2 interface of a Concordium node in the format "address:port". Defaults to 'localhost:20000' 19 | --subindex, The subindex of the smart contract. Defaults to 0 20 | `, 21 | { 22 | importMeta: import.meta, 23 | flags: { 24 | endpoint: { 25 | type: 'string', 26 | alias: 'e', 27 | default: 'localhost:20000', 28 | }, 29 | index: { 30 | type: 'number', 31 | alias: 'i', 32 | isRequired: true, 33 | }, 34 | subindex: { 35 | type: 'number', 36 | default: 0, 37 | }, 38 | }, 39 | } 40 | ); 41 | 42 | const [address, port] = parseEndpoint(cli.flags.endpoint); 43 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 44 | 45 | (async () => { 46 | const contract = await CIS4Contract.create(client, ContractAddress.create(cli.flags.index, cli.flags.subindex)); 47 | 48 | const metadata = await contract.registryMetadata(); 49 | console.log('Metadata:', metadata); 50 | })(); 51 | -------------------------------------------------------------------------------- /examples/nodejs/cis4/revocationKeys.ts: -------------------------------------------------------------------------------- 1 | import { CIS4Contract, ContractAddress } from '@concordium/web-sdk'; 2 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 3 | import { credentials } from '@grpc/grpc-js'; 4 | import meow from 'meow'; 5 | 6 | import { parseEndpoint } from '../shared/util.js'; 7 | 8 | const cli = meow( 9 | ` 10 | Usage 11 | $ yarn run-example [options] 12 | 13 | Required 14 | --index, -i The index of the smart contract 15 | 16 | Options 17 | --help, -h Displays this message 18 | --endpoint, -e Specify endpoint of a grpc2 interface of a Concordium node in the format "address:port". Defaults to 'localhost:20000' 19 | --subindex, The subindex of the smart contract. Defaults to 0 20 | `, 21 | { 22 | importMeta: import.meta, 23 | flags: { 24 | endpoint: { 25 | type: 'string', 26 | alias: 'e', 27 | default: 'localhost:20000', 28 | }, 29 | index: { 30 | type: 'number', 31 | alias: 'i', 32 | isRequired: true, 33 | }, 34 | subindex: { 35 | type: 'number', 36 | default: 0, 37 | }, 38 | }, 39 | } 40 | ); 41 | 42 | const [address, port] = parseEndpoint(cli.flags.endpoint); 43 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 44 | 45 | (async () => { 46 | const contract = await CIS4Contract.create(client, ContractAddress.create(cli.flags.index, cli.flags.subindex)); 47 | 48 | const keys = await contract.revocationKeys(); 49 | console.log('Revocation keys:', keys); 50 | })(); 51 | -------------------------------------------------------------------------------- /examples/nodejs/client/banPeer.ts: -------------------------------------------------------------------------------- 1 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 2 | import { credentials } from '@grpc/grpc-js'; 3 | import meow from 'meow'; 4 | 5 | import { parseEndpoint } from '../shared/util.js'; 6 | 7 | const cli = meow( 8 | ` 9 | Usage 10 | $ yarn run-example [options] 11 | 12 | Required 13 | --ip, -i The ip of the peer to ban. 14 | 15 | Options 16 | --help, Displays this message 17 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 18 | `, 19 | { 20 | importMeta: import.meta, 21 | flags: { 22 | ip: { 23 | type: 'string', 24 | alias: 'i', 25 | isRequired: true, 26 | }, 27 | endpoint: { 28 | type: 'string', 29 | alias: 'e', 30 | default: 'localhost:20000', 31 | }, 32 | }, 33 | } 34 | ); 35 | 36 | const [address, port] = parseEndpoint(cli.flags.endpoint); 37 | 38 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 39 | 40 | /** 41 | * Bans the specified peer. 42 | * Rejects if the action fails. 43 | */ 44 | 45 | (async () => { 46 | // #region documentation-snippet 47 | await client.banPeer(cli.flags.ip); 48 | console.log('Specified peer successfully banned'); 49 | // #endregion documentation-snippet 50 | })(); 51 | -------------------------------------------------------------------------------- /examples/nodejs/client/dumpStart.ts: -------------------------------------------------------------------------------- 1 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 2 | import { credentials } from '@grpc/grpc-js'; 3 | import meow from 'meow'; 4 | 5 | import { parseEndpoint } from '../shared/util.js'; 6 | 7 | const cli = meow( 8 | ` 9 | Usage 10 | $ yarn run-example [options] 11 | 12 | Required 13 | --filepath, -f Specifies which file to dump the packages into 14 | 15 | Options 16 | --help, Displays this message 17 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 18 | --dump-raw, -d Specifies whether the node should dump raw packages 19 | `, 20 | { 21 | importMeta: import.meta, 22 | flags: { 23 | filepath: { 24 | type: 'string', 25 | alias: 'f', 26 | isRequired: true, 27 | }, 28 | endpoint: { 29 | type: 'string', 30 | alias: 'e', 31 | default: 'localhost:20000', 32 | }, 33 | dumpRaw: { 34 | type: 'boolean', 35 | alias: 'd', 36 | default: false, 37 | }, 38 | }, 39 | } 40 | ); 41 | 42 | const [address, port] = parseEndpoint(cli.flags.endpoint); 43 | 44 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 45 | 46 | /** 47 | * Start dumping packages into the specified file. Only enabled if the node was 48 | * built with the `network_dump` feature. Rejects if the network dump failed 49 | * to start. 50 | 51 | * The first argument specifies which file to dump the packages into. 52 | * The second parameter specifies whether the node should dump raw packages. 53 | */ 54 | 55 | (async () => { 56 | // #region documentation-snippet 57 | await client.dumpStart(cli.flags.filepath, cli.flags.dumpRaw); 58 | console.log('Dump successfully started'); 59 | // #endregion documentation-snippet 60 | })(); 61 | -------------------------------------------------------------------------------- /examples/nodejs/client/dumpStop.ts: -------------------------------------------------------------------------------- 1 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 2 | import { credentials } from '@grpc/grpc-js'; 3 | import meow from 'meow'; 4 | 5 | import { parseEndpoint } from '../shared/util.js'; 6 | 7 | const cli = meow( 8 | ` 9 | Usage 10 | $ yarn run-example [options] 11 | 12 | Options 13 | --help, Displays this message 14 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 15 | `, 16 | { 17 | importMeta: import.meta, 18 | flags: { 19 | endpoint: { 20 | type: 'string', 21 | alias: 'e', 22 | default: 'localhost:20000', 23 | }, 24 | }, 25 | } 26 | ); 27 | 28 | const [address, port] = parseEndpoint(cli.flags.endpoint); 29 | 30 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 31 | 32 | /** 33 | * Stop dumping packages. Only enabled if the node was built with the 34 | * `network_dump` feature. Rejects if the network dump failed to be stopped. 35 | */ 36 | 37 | (async () => { 38 | // #region documentation-snippet 39 | await client.dumpStop(); 40 | console.log('Dump successfully stopped'); 41 | // #endregion documentation-snippet 42 | })(); 43 | -------------------------------------------------------------------------------- /examples/nodejs/client/getBannedPeers.ts: -------------------------------------------------------------------------------- 1 | import { IpAddressString } from '@concordium/web-sdk'; 2 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 3 | import { credentials } from '@grpc/grpc-js'; 4 | import meow from 'meow'; 5 | 6 | import { parseEndpoint } from '../shared/util.js'; 7 | 8 | const cli = meow( 9 | ` 10 | Usage 11 | $ yarn run-example [options] 12 | 13 | Options 14 | --help, Displays this message 15 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 16 | `, 17 | { 18 | importMeta: import.meta, 19 | flags: { 20 | endpoint: { 21 | type: 'string', 22 | alias: 'e', 23 | default: 'localhost:20000', 24 | }, 25 | }, 26 | } 27 | ); 28 | 29 | const [address, port] = parseEndpoint(cli.flags.endpoint); 30 | 31 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 32 | 33 | /** 34 | * Get a list of banned peers. 35 | */ 36 | 37 | (async () => { 38 | // #region documentation-snippet 39 | const bannedPeers: IpAddressString[] = await client.getBannedPeers(); 40 | // #endregion documentation-snippet 41 | 42 | console.log('Banned peers:'); 43 | console.log(bannedPeers); 44 | })(); 45 | -------------------------------------------------------------------------------- /examples/nodejs/client/getBlockInfo.ts: -------------------------------------------------------------------------------- 1 | import { BlockHash, BlockInfo } from '@concordium/web-sdk'; 2 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 3 | import { credentials } from '@grpc/grpc-js'; 4 | import meow from 'meow'; 5 | 6 | import { parseEndpoint } from '../shared/util.js'; 7 | 8 | const cli = meow( 9 | ` 10 | Usage 11 | $ yarn run-example [options] 12 | 13 | Options 14 | --help, Displays this message 15 | --block, -b A block to query from, defaults to last final block 16 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 17 | `, 18 | { 19 | importMeta: import.meta, 20 | flags: { 21 | endpoint: { 22 | type: 'string', 23 | alias: 'e', 24 | default: 'localhost:20000', 25 | }, 26 | block: { 27 | type: 'string', 28 | alias: 'b', 29 | }, 30 | }, 31 | } 32 | ); 33 | 34 | const [address, port] = parseEndpoint(cli.flags.endpoint); 35 | 36 | const client = new ConcordiumGRPCNodeClient(address, port, credentials.createInsecure()); 37 | 38 | /** 39 | * Retrieves information about a specific block. 40 | * If a blockhash is not supplied it will pick the latest finalized block. 41 | */ 42 | 43 | (async () => { 44 | // #region documentation-snippet 45 | const blockHash = cli.flags.block === undefined ? undefined : BlockHash.fromHexString(cli.flags.block); 46 | const blockInfo: BlockInfo = await client.getBlockInfo(blockHash); 47 | // #endregion documentation-snippet 48 | 49 | console.dir(blockInfo, { depth: null, colors: true }); 50 | })(); 51 | -------------------------------------------------------------------------------- /examples/nodejs/client/getBlocks.ts: -------------------------------------------------------------------------------- 1 | import { ArrivedBlockInfo } from '@concordium/web-sdk'; 2 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 3 | import { credentials } from '@grpc/grpc-js'; 4 | import meow from 'meow'; 5 | 6 | import { parseEndpoint } from '../shared/util.js'; 7 | 8 | const cli = meow( 9 | ` 10 | Usage 11 | $ yarn run-example [options] 12 | 13 | Options 14 | --help, Displays this message 15 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 16 | `, 17 | { 18 | importMeta: import.meta, 19 | flags: { 20 | endpoint: { 21 | type: 'string', 22 | alias: 'e', 23 | default: 'localhost:20000', 24 | }, 25 | }, 26 | } 27 | ); 28 | 29 | const [address, port] = parseEndpoint(cli.flags.endpoint); 30 | 31 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 32 | 33 | /** 34 | * Returns a stream of blocks that is iterable. The following code will receive 35 | * blocks as long as there is a connection to the node: 36 | */ 37 | 38 | (async () => { 39 | // #region documentation-snippet 40 | // Get block stream 41 | const blocks: AsyncIterable = client.getBlocks(); 42 | 43 | // Prints blocks infinitely 44 | for await (const block of blocks) { 45 | console.log('Arrived block height:', block.height); 46 | console.log('Arrived block hash:', block.hash, '\n'); 47 | } 48 | // #endregion documentation-snippet 49 | })(); 50 | -------------------------------------------------------------------------------- /examples/nodejs/client/getBlocksAbort.ts: -------------------------------------------------------------------------------- 1 | import { ArrivedBlockInfo } from '@concordium/web-sdk'; 2 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 3 | import { credentials } from '@grpc/grpc-js'; 4 | import meow from 'meow'; 5 | 6 | import { parseEndpoint } from '../shared/util.js'; 7 | 8 | const cli = meow( 9 | ` 10 | Usage 11 | $ yarn run-example [options] 12 | 13 | Options 14 | --help, -h Displays this message 15 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 16 | `, 17 | { 18 | importMeta: import.meta, 19 | flags: { 20 | endpoint: { 21 | type: 'string', 22 | alias: 'e', 23 | default: 'localhost:20000', 24 | }, 25 | }, 26 | } 27 | ); 28 | 29 | const [address, port] = parseEndpoint(cli.flags.endpoint); 30 | 31 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 32 | 33 | /** 34 | * Returns a stream of blocks that is iterable. The following code will receive 35 | * a single block and then abort: 36 | */ 37 | 38 | (async () => { 39 | // #region documentation-snippet 40 | // Create abort controller and block stream 41 | const ac = new AbortController(); 42 | const blockStream: AsyncIterable = client.getBlocks(ac.signal); 43 | 44 | // Only get one item then break 45 | for await (const block of blockStream) { 46 | console.log('Arrived block height:', block.height); 47 | console.log('Arrived block hash:', block.hash, '\n'); 48 | break; 49 | } 50 | 51 | // Closes the stream 52 | ac.abort(); 53 | // #endregion documentation-snippet 54 | })(); 55 | -------------------------------------------------------------------------------- /examples/nodejs/client/getBlocksAtHeightAbsolute.ts: -------------------------------------------------------------------------------- 1 | import { BlockHash } from '@concordium/web-sdk'; 2 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 3 | import { credentials } from '@grpc/grpc-js'; 4 | import meow from 'meow'; 5 | 6 | import { parseEndpoint } from '../shared/util.js'; 7 | 8 | const cli = meow( 9 | ` 10 | Usage 11 | $ yarn run-example [options] 12 | 13 | Required 14 | --height, The block height to get blocks from 15 | 16 | Options 17 | --help, Displays this message 18 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 19 | `, 20 | { 21 | importMeta: import.meta, 22 | flags: { 23 | height: { 24 | type: 'number', 25 | alias: 'h', 26 | isRequired: true, 27 | }, 28 | endpoint: { 29 | type: 'string', 30 | alias: 'e', 31 | default: 'localhost:20000', 32 | }, 33 | }, 34 | } 35 | ); 36 | 37 | const [address, port] = parseEndpoint(cli.flags.endpoint); 38 | 39 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 40 | 41 | /** 42 | * Get a list of live blocks at a given absolute height. 43 | */ 44 | 45 | (async () => { 46 | // #region documentation-snippet 47 | const blocks: BlockHash.Type[] = await client.getBlocksAtHeight(BigInt(cli.flags.height)); 48 | // #endregion documentation-snippet 49 | 50 | for (const block of blocks) { 51 | console.log(block); 52 | } 53 | })(); 54 | -------------------------------------------------------------------------------- /examples/nodejs/client/getBranches.ts: -------------------------------------------------------------------------------- 1 | import { Branch } from '@concordium/web-sdk'; 2 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 3 | import { credentials } from '@grpc/grpc-js'; 4 | import meow from 'meow'; 5 | 6 | import { parseEndpoint } from '../shared/util.js'; 7 | 8 | const cli = meow( 9 | ` 10 | Usage 11 | $ yarn run-example [options] 12 | 13 | Options 14 | --help, Displays this message 15 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 16 | `, 17 | { 18 | importMeta: import.meta, 19 | flags: { 20 | endpoint: { 21 | type: 'string', 22 | alias: 'e', 23 | default: 'localhost:20000', 24 | }, 25 | }, 26 | } 27 | ); 28 | 29 | const [address, port] = parseEndpoint(cli.flags.endpoint); 30 | 31 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 32 | 33 | /** 34 | * Get the current branches of blocks starting from and including the last 35 | * finalized block. 36 | */ 37 | 38 | (async () => { 39 | // #region documentation-snippet 40 | const branch: Branch = await client.getBranches(); 41 | 42 | console.log('Root hash:', branch.blockHash); 43 | console.log("Root's children:"); 44 | console.dir(branch.children, { depth: null, colors: true }); 45 | // #endregion documentation-snippet 46 | })(); 47 | -------------------------------------------------------------------------------- /examples/nodejs/client/getConsensusStatus.ts: -------------------------------------------------------------------------------- 1 | import { ConsensusStatus } from '@concordium/web-sdk'; 2 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 3 | import { credentials } from '@grpc/grpc-js'; 4 | import meow from 'meow'; 5 | 6 | import { parseEndpoint } from '../shared/util.js'; 7 | 8 | const cli = meow( 9 | ` 10 | Usage 11 | $ yarn run-example [options] 12 | 13 | Options 14 | --help, Displays this message 15 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 16 | `, 17 | { 18 | importMeta: import.meta, 19 | flags: { 20 | endpoint: { 21 | type: 'string', 22 | alias: 'e', 23 | default: 'localhost:20000', 24 | }, 25 | }, 26 | } 27 | ); 28 | 29 | const [address, port] = parseEndpoint(cli.flags.endpoint); 30 | 31 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 32 | 33 | /** 34 | * Retrieves the current consensus status from the node. 35 | */ 36 | 37 | (async () => { 38 | // #region documentation-snippet 39 | const consensusStatus: ConsensusStatus = await client.getConsensusStatus(); 40 | // #endregion documentation-snippet 41 | 42 | console.dir(consensusStatus, { depth: null, colors: true }); 43 | })(); 44 | -------------------------------------------------------------------------------- /examples/nodejs/client/getCryptographicParameters.ts: -------------------------------------------------------------------------------- 1 | import { BlockHash, CryptographicParameters } from '@concordium/web-sdk'; 2 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 3 | import { credentials } from '@grpc/grpc-js'; 4 | import meow from 'meow'; 5 | 6 | import { parseEndpoint } from '../shared/util.js'; 7 | 8 | const cli = meow( 9 | ` 10 | Usage 11 | $ yarn run-example [options] 12 | 13 | Options 14 | --help, -h Displays this message 15 | --block, -b A block to query from, defaults to last final block 16 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 17 | `, 18 | { 19 | importMeta: import.meta, 20 | flags: { 21 | block: { 22 | type: 'string', 23 | alias: 'b', 24 | }, 25 | endpoint: { 26 | type: 'string', 27 | alias: 'e', 28 | default: 'localhost:20000', 29 | }, 30 | }, 31 | } 32 | ); 33 | 34 | const [address, port] = parseEndpoint(cli.flags.endpoint); 35 | 36 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 37 | 38 | /** 39 | * Retrieves the global cryptographic parameters for the blockchain at a specific 40 | * block. These are a required input for e.g. creating credentials. 41 | */ 42 | 43 | (async () => { 44 | // #region documentation-snippet 45 | const blockHash = cli.flags.block === undefined ? undefined : BlockHash.fromHexString(cli.flags.block); 46 | const parameters: CryptographicParameters = await client.getCryptographicParameters(blockHash); 47 | // #endregion documentation-snippet 48 | 49 | console.log('Genesis string:', parameters.genesisString); 50 | })(); 51 | -------------------------------------------------------------------------------- /examples/nodejs/client/getEmbeddedSchema.ts: -------------------------------------------------------------------------------- 1 | import { ModuleReference } from '@concordium/web-sdk'; 2 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 3 | import { credentials } from '@grpc/grpc-js'; 4 | import fs from 'fs'; 5 | import meow from 'meow'; 6 | 7 | const cli = meow( 8 | ` 9 | Usage 10 | $ yarn run-example [options] 11 | 12 | Required 13 | --module, -m The module reference of the module from which we wish to get the schema 14 | --out-path, -o The path to write the module schema to 15 | 16 | Options 17 | --help, Displays this message 18 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 19 | `, 20 | { 21 | importMeta: import.meta, 22 | flags: { 23 | module: { 24 | type: 'string', 25 | alias: 'm', 26 | isRequired: true, 27 | }, 28 | outPath: { 29 | type: 'string', 30 | alias: 'o', 31 | isRequired: true, 32 | }, 33 | endpoint: { 34 | type: 'string', 35 | alias: 'e', 36 | default: 'localhost:20000', 37 | }, 38 | }, 39 | } 40 | ); 41 | 42 | const [address, port] = cli.flags.endpoint.split(':'); 43 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 44 | 45 | /** 46 | * Gets an embedded schema from a provided module. 47 | */ 48 | 49 | (async () => { 50 | // #region documentation-snippet 51 | const moduleRef = ModuleReference.fromHexString(cli.flags.module); 52 | const schema = await client.getEmbeddedSchema(moduleRef); 53 | // #endregion documentation-snippet 54 | 55 | if (schema) { 56 | fs.writeFileSync(cli.flags.outPath, new Uint8Array(schema.buffer)); 57 | } 58 | 59 | console.log('Wrote schema to file: ', cli.flags.outPath); 60 | })(); 61 | -------------------------------------------------------------------------------- /examples/nodejs/client/getFinalizedBlocks.ts: -------------------------------------------------------------------------------- 1 | import { FinalizedBlockInfo } from '@concordium/web-sdk'; 2 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 3 | import { credentials } from '@grpc/grpc-js'; 4 | import meow from 'meow'; 5 | 6 | import { parseEndpoint } from '../shared/util.js'; 7 | 8 | const cli = meow( 9 | ` 10 | Usage 11 | $ yarn run-example [options] 12 | 13 | Options 14 | --help, -h Displays this message 15 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 16 | `, 17 | { 18 | importMeta: import.meta, 19 | flags: { 20 | endpoint: { 21 | type: 'string', 22 | alias: 'e', 23 | default: 'localhost:20000', 24 | }, 25 | }, 26 | } 27 | ); 28 | 29 | const [address, port] = parseEndpoint(cli.flags.endpoint); 30 | 31 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 32 | 33 | /* 34 | * Returns a stream of finalized blocks that is iterable. The following code will receive 35 | * blocks as long as there is a connection to the node: 36 | */ 37 | 38 | (async () => { 39 | // #region documentation-snippet 40 | // Get block stream 41 | const blockStream: AsyncIterable = client.getFinalizedBlocks(); 42 | 43 | // Prints blocks infinitely 44 | for await (const block of blockStream) { 45 | console.log('Arrived block height:', block.height); 46 | console.log('Arrived block hash:', block.hash, '\n'); 47 | } 48 | // #endregion documentation-snippet 49 | })(); 50 | -------------------------------------------------------------------------------- /examples/nodejs/client/getFinalizedBlocksFrom.ts: -------------------------------------------------------------------------------- 1 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 2 | import { credentials } from '@grpc/grpc-js'; 3 | import meow from 'meow'; 4 | 5 | import { parseEndpoint } from '../shared/util.js'; 6 | 7 | const cli = meow( 8 | ` 9 | Usage 10 | $ yarn run-example [options] 11 | 12 | Required 13 | --height, The block height to get blocks from 14 | 15 | Options 16 | --help, Displays this message 17 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 18 | --numBlocks, -n The number of blocks to process 19 | `, 20 | { 21 | importMeta: import.meta, 22 | flags: { 23 | height: { 24 | type: 'number', 25 | alias: 'h', 26 | isRequired: true, 27 | }, 28 | numBlocks: { 29 | type: 'number', 30 | alias: 'n', 31 | }, 32 | endpoint: { 33 | type: 'string', 34 | alias: 'e', 35 | default: 'localhost:20000', 36 | }, 37 | }, 38 | } 39 | ); 40 | 41 | const [address, port] = parseEndpoint(cli.flags.endpoint); 42 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 43 | 44 | /** 45 | * Get a stream of finalized blocks from "--endpoint", starting from "--height". 46 | */ 47 | 48 | (async () => { 49 | // #region documentation-snippet 50 | const ac = new AbortController(); 51 | const bis = client.getFinalizedBlocksFrom(BigInt(cli.flags.height), ac.signal); 52 | 53 | let i = 0; 54 | const n = cli.flags.numBlocks; 55 | 56 | for await (const bi of bis) { 57 | console.log(bi); 58 | 59 | i++; 60 | if (n !== undefined && i > n - 1) { 61 | ac.abort(); 62 | break; 63 | } 64 | } 65 | // #endregion documentation-snippet 66 | })(); 67 | -------------------------------------------------------------------------------- /examples/nodejs/client/getNextUpdateSequenceNumbers.ts: -------------------------------------------------------------------------------- 1 | import { BlockHash, NextUpdateSequenceNumbers } from '@concordium/web-sdk'; 2 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 3 | import { credentials } from '@grpc/grpc-js'; 4 | import meow from 'meow'; 5 | 6 | import { parseEndpoint } from '../shared/util.js'; 7 | 8 | const cli = meow( 9 | ` 10 | Usage 11 | $ yarn run-example [options] 12 | 13 | Options 14 | --help, -h Displays this message 15 | --block, -b A block to query from, defaults to last final block 16 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 17 | `, 18 | { 19 | importMeta: import.meta, 20 | flags: { 21 | block: { 22 | type: 'string', 23 | alias: 'b', 24 | }, 25 | endpoint: { 26 | type: 'string', 27 | alias: 'e', 28 | default: 'localhost:20000', 29 | }, 30 | }, 31 | } 32 | ); 33 | 34 | const [address, port] = parseEndpoint(cli.flags.endpoint); 35 | 36 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 37 | 38 | /** 39 | * Get next available sequence numbers for updating chain parameters after a 40 | * given block. 41 | */ 42 | 43 | (async () => { 44 | // #region documentation-snippet 45 | const blockHash = cli.flags.block === undefined ? undefined : BlockHash.fromHexString(cli.flags.block); 46 | const updateSeqNums: NextUpdateSequenceNumbers = await client.getNextUpdateSequenceNumbers(blockHash); 47 | // #endregion documentation-snippet 48 | 49 | console.dir(updateSeqNums, { depth: null, colors: true }); 50 | })(); 51 | -------------------------------------------------------------------------------- /examples/nodejs/client/getNodeInfo.ts: -------------------------------------------------------------------------------- 1 | import { NodeInfo } from '@concordium/web-sdk'; 2 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 3 | import { credentials } from '@grpc/grpc-js'; 4 | import meow from 'meow'; 5 | 6 | import { parseEndpoint } from '../shared/util.js'; 7 | 8 | const cli = meow( 9 | ` 10 | Usage 11 | $ yarn run-example [options] 12 | 13 | Options 14 | --help, -h Displays this message 15 | --block, -b A block to query from, defaults to last final block 16 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 17 | `, 18 | { 19 | importMeta: import.meta, 20 | flags: { 21 | block: { 22 | type: 'string', 23 | alias: 'b', 24 | }, 25 | endpoint: { 26 | type: 'string', 27 | alias: 'e', 28 | default: 'localhost:20000', 29 | }, 30 | }, 31 | } 32 | ); 33 | 34 | const [address, port] = parseEndpoint(cli.flags.endpoint); 35 | 36 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 37 | 38 | /** 39 | * Get information about the node. 40 | 41 | * The `NodeInfo` includes information of: 42 | * - Meta information, such as the, version of the node, type of the node, uptime 43 | * and the local time of the node. 44 | * - NetworkInfo, which yields data such as the node id, packets sent/received, 45 | * average bytes per second sent/received. 46 | * - ConsensusStatus. The `ConsensusStatus` returned depends on if the node supports 47 | * the protocol on chain and whether the node is configured as a baker or not. 48 | */ 49 | 50 | (async () => { 51 | // #region documentation-snippet 52 | const nodeInfo: NodeInfo = await client.getNodeInfo(); 53 | // #endregion documentation-snippet 54 | 55 | console.dir(nodeInfo, { depth: null, colors: true }); 56 | })(); 57 | -------------------------------------------------------------------------------- /examples/nodejs/client/getPeersInfo.ts: -------------------------------------------------------------------------------- 1 | import { PeerInfo } from '@concordium/web-sdk'; 2 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 3 | import { credentials } from '@grpc/grpc-js'; 4 | import meow from 'meow'; 5 | 6 | import { parseEndpoint } from '../shared/util.js'; 7 | 8 | const cli = meow( 9 | ` 10 | Usage 11 | $ yarn run-example [options] 12 | 13 | Options 14 | --help, -h Displays this message 15 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 16 | `, 17 | { 18 | importMeta: import.meta, 19 | flags: { 20 | endpoint: { 21 | type: 'string', 22 | alias: 'e', 23 | default: 'localhost:20000', 24 | }, 25 | }, 26 | } 27 | ); 28 | 29 | const [address, port] = parseEndpoint(cli.flags.endpoint); 30 | 31 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 32 | 33 | /** 34 | * Get a list of the peers that the node is connected to and associated network 35 | * related information for each peer. 36 | */ 37 | 38 | (async () => { 39 | // #region documentation-snippet 40 | const peerInfo: PeerInfo[] = await client.getPeersInfo(); 41 | // #endregion documentation-snippet 42 | 43 | console.dir(peerInfo, { depth: null, colors: true }); 44 | })(); 45 | -------------------------------------------------------------------------------- /examples/nodejs/client/healthCheck.ts: -------------------------------------------------------------------------------- 1 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 2 | import { credentials } from '@grpc/grpc-js'; 3 | import meow from 'meow'; 4 | 5 | import { parseEndpoint } from '../shared/util.js'; 6 | 7 | const cli = meow( 8 | ` 9 | Usage 10 | $ yarn run-example [options] 11 | 12 | Options 13 | --help, Displays this message 14 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 15 | `, 16 | { 17 | importMeta: import.meta, 18 | flags: { 19 | endpoint: { 20 | type: 'string', 21 | alias: 'e', 22 | default: 'localhost:20000', 23 | }, 24 | }, 25 | } 26 | ); 27 | 28 | const [address, port] = parseEndpoint(cli.flags.endpoint); 29 | 30 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 31 | 32 | /** 33 | * Queries the node for its health 34 | */ 35 | (async () => { 36 | // #region documentation-snippet 37 | const check = await client.healthCheck(); 38 | if (check.isHealthy) { 39 | console.log('The node is healthy!'); 40 | } else { 41 | console.log('The node is not healthy'); 42 | console.log('Message: ' + check.message); 43 | } 44 | // #endregion documentation-snippet 45 | })(); 46 | -------------------------------------------------------------------------------- /examples/nodejs/client/peerConnect.ts: -------------------------------------------------------------------------------- 1 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 2 | import { credentials } from '@grpc/grpc-js'; 3 | import meow from 'meow'; 4 | 5 | import { parseEndpoint } from '../shared/util.js'; 6 | 7 | const cli = meow( 8 | ` 9 | Usage 10 | $ yarn run-example [options] 11 | 12 | Required 13 | --ip, -i The ip of the peer to connect to. 14 | --port, -p The port of the peer to connect to. 15 | 16 | Options 17 | --help, Displays this message 18 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 19 | `, 20 | { 21 | importMeta: import.meta, 22 | flags: { 23 | ip: { 24 | type: 'string', 25 | alias: 'i', 26 | isRequired: true, 27 | }, 28 | port: { 29 | type: 'number', 30 | alias: 'p', 31 | isRequired: true, 32 | }, 33 | endpoint: { 34 | type: 'string', 35 | alias: 'e', 36 | default: 'localhost:20000', 37 | }, 38 | }, 39 | } 40 | ); 41 | 42 | const [address, port] = parseEndpoint(cli.flags.endpoint); 43 | 44 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 45 | 46 | /** 47 | * Suggest to connect the specified address as a peer. This, if successful, 48 | * adds the peer to the list of given addresses, otherwise rejects. Note that 49 | * the peer might not be connected to instantly, in that case the node will 50 | * try to establish the connection in the near future. 51 | */ 52 | 53 | (async () => { 54 | // #region documentation-snippet 55 | await client.peerConnect(cli.flags.ip, cli.flags.port); 56 | console.log('Successfully connected to peer'); 57 | // #endregion documentation-snippet 58 | })(); 59 | -------------------------------------------------------------------------------- /examples/nodejs/client/peerDisconnect.ts: -------------------------------------------------------------------------------- 1 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 2 | import { credentials } from '@grpc/grpc-js'; 3 | import meow from 'meow'; 4 | 5 | import { parseEndpoint } from '../shared/util.js'; 6 | 7 | const cli = meow( 8 | ` 9 | Usage 10 | $ yarn run-example [options] 11 | 12 | Required 13 | --ip, -i The ip of the peer to connect to. 14 | --port, -p The port of the peer to connect to. 15 | 16 | Options 17 | --help, Displays this message 18 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 19 | `, 20 | { 21 | importMeta: import.meta, 22 | flags: { 23 | ip: { 24 | type: 'string', 25 | alias: 'i', 26 | isRequired: true, 27 | }, 28 | port: { 29 | type: 'number', 30 | alias: 'p', 31 | isRequired: true, 32 | }, 33 | endpoint: { 34 | type: 'string', 35 | alias: 'e', 36 | default: 'localhost:20000', 37 | }, 38 | }, 39 | } 40 | ); 41 | 42 | const [address, port] = parseEndpoint(cli.flags.endpoint); 43 | 44 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 45 | 46 | /** 47 | * Disconnect from the peer and remove them from the given addresses list 48 | * if they are on it. Resolves if the request was processed successfully. 49 | * Otherwise rejects. 50 | */ 51 | 52 | (async () => { 53 | // #region documentation-snippet 54 | await client.peerDisconnect(cli.flags.ip, cli.flags.port); 55 | console.log('Successfully disconnected from peer'); 56 | // #endregion documentation-snippet 57 | })(); 58 | -------------------------------------------------------------------------------- /examples/nodejs/client/shutdown.ts: -------------------------------------------------------------------------------- 1 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 2 | import { credentials } from '@grpc/grpc-js'; 3 | import meow from 'meow'; 4 | 5 | import { parseEndpoint } from '../shared/util.js'; 6 | 7 | const cli = meow( 8 | ` 9 | Usage 10 | $ yarn run-example [options] 11 | 12 | Options 13 | --help, Displays this message 14 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 15 | `, 16 | { 17 | importMeta: import.meta, 18 | flags: { 19 | endpoint: { 20 | type: 'string', 21 | alias: 'e', 22 | default: 'localhost:20000', 23 | }, 24 | }, 25 | } 26 | ); 27 | 28 | const [address, port] = parseEndpoint(cli.flags.endpoint); 29 | 30 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 31 | 32 | /** 33 | * Shuts down the node. 34 | */ 35 | 36 | (async () => { 37 | // #region documentation-snippet 38 | await client.shutdown(); 39 | console.log('Node succesfully shut down'); 40 | // #endregion documentation-snippet 41 | })(); 42 | -------------------------------------------------------------------------------- /examples/nodejs/client/unbanPeer.ts: -------------------------------------------------------------------------------- 1 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 2 | import { credentials } from '@grpc/grpc-js'; 3 | import meow from 'meow'; 4 | 5 | import { parseEndpoint } from '../shared/util.js'; 6 | 7 | const cli = meow( 8 | ` 9 | Usage 10 | $ yarn run-example [options] 11 | 12 | Required 13 | --ip, -i The ip of the peer to connect to. 14 | 15 | Options 16 | --help, Displays this message 17 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 18 | `, 19 | { 20 | importMeta: import.meta, 21 | flags: { 22 | ip: { 23 | type: 'string', 24 | alias: 'i', 25 | isRequired: true, 26 | }, 27 | endpoint: { 28 | type: 'string', 29 | alias: 'e', 30 | default: 'localhost:20000', 31 | }, 32 | }, 33 | } 34 | ); 35 | 36 | const [address, port] = parseEndpoint(cli.flags.endpoint); 37 | 38 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 39 | 40 | /** 41 | * Unbans the specified peer. 42 | * Rejects if the action fails. 43 | */ 44 | 45 | (async () => { 46 | // #region documentation-snippet 47 | await client.unbanPeer(cli.flags.ip); 48 | console.log('Successfully unbanned peer'); 49 | // #endregion documentation-snippet 50 | })(); 51 | -------------------------------------------------------------------------------- /examples/nodejs/common/aliases.ts: -------------------------------------------------------------------------------- 1 | import { AccountAddress } from '@concordium/web-sdk'; 2 | 3 | /** 4 | * The following shows how to generate an account alias, and how to test 5 | * whether an account is an alias. The alias is an alternative address, which 6 | * is connected to the same account. The getAlias function takes a counter 7 | * (0 <= counter < 2^24) to determine which alias to return. 8 | */ 9 | 10 | // #region documentation-snippet 11 | const accountAddress = AccountAddress.fromBase58('3sAHwfehRNEnXk28W7A3XB3GzyBiuQkXLNRmDwDGPUe8JsoAcU'); 12 | const seperateAccount = AccountAddress.fromBase58('4ZJBYQbVp3zVZyjCXfZAAYBVkJMyVj8UKUNj9ox5YqTCBdBq2M'); 13 | 14 | const aliasCounter = 0; 15 | const alias: AccountAddress.Type = AccountAddress.getAlias(accountAddress, aliasCounter); 16 | 17 | console.log('Original address:', accountAddress.address); 18 | console.log('Alias address:', alias.address); 19 | 20 | // The function `isAlias` can be used to check if two acounts are aliases 21 | if (!AccountAddress.isAlias(alias, accountAddress)) { 22 | throw Error('Expected accounts to be aliases!'); 23 | } 24 | 25 | // Of course, using `isAlias` on a completely seperate account returns false 26 | if (AccountAddress.isAlias(accountAddress, seperateAccount)) { 27 | throw Error('Two seperate accounts are claimed to be aliases!'); 28 | } 29 | // #endregion documentation-snippet 30 | -------------------------------------------------------------------------------- /examples/nodejs/common/buildAccountSigner.ts: -------------------------------------------------------------------------------- 1 | import { AccountAddress, buildAccountSigner, parseWallet, signMessage } from '@concordium/web-sdk'; 2 | import fs from 'fs'; 3 | import meow from 'meow'; 4 | import path from 'path'; 5 | 6 | const cli = meow( 7 | ` 8 | Usage 9 | $ yarn run-example [options] 10 | 11 | Required 12 | --wallet-file, -w A path to a wallet export file from a Concordium wallet 13 | 14 | Options 15 | --help, Displays this message 16 | `, 17 | { 18 | importMeta: import.meta, 19 | flags: { 20 | walletFile: { 21 | type: 'string', 22 | alias: 'w', 23 | isRequired: true, 24 | }, 25 | }, 26 | } 27 | ); 28 | 29 | /** 30 | * Shows how to build an account signer 31 | */ 32 | 33 | // #region documentation-snippet 34 | const walletFile = fs.readFileSync(path.resolve(process.cwd(), cli.flags.walletFile), 'utf8'); 35 | const wallet = parseWallet(walletFile); 36 | 37 | try { 38 | const signer = buildAccountSigner(wallet); 39 | 40 | signMessage(AccountAddress.fromBase58(wallet.value.address), 'test', signer).then(console.log); 41 | } catch { 42 | console.error('File passed does not conform to a supported JSON format'); 43 | } 44 | // #endregion documentation-snippet 45 | -------------------------------------------------------------------------------- /examples/nodejs/common/statements.ts: -------------------------------------------------------------------------------- 1 | import { AttributesKeys, IdStatementBuilder, verifyIdstatement } from '@concordium/web-sdk'; 2 | 3 | /** 4 | * The following example shows how a proof statement can be built up. 5 | */ 6 | 7 | const statementBuilder = new IdStatementBuilder(); 8 | 9 | // #region documentation-snippet 10 | // Prover's age must be over 18: 11 | statementBuilder.addMinimumAge(18); 12 | 13 | // Prover's country of nationality to be a EU member state: 14 | statementBuilder.addEUNationality(); 15 | // Prover's country of residency to be a EU member state: 16 | statementBuilder.addEUResidency(); 17 | 18 | // Prover must not be living in Germany or Poland. 19 | //statementBuilder.addNonMembership(AttributesKeys.countryOfResidence, [ 20 | // 'DE', 21 | // 'PT', 22 | //]); 23 | 24 | // We also reveal the type of documentation of the prover. 25 | statementBuilder.revealAttribute(AttributesKeys.idDocType); 26 | 27 | // The statement we wish to prove: 28 | const statement = statementBuilder.getStatement(); 29 | 30 | // Test that the statement is well formed (validly constructed). 31 | // Will throw otherwise. 32 | verifyIdstatement(statement); 33 | 34 | console.log('Succesfully constructed statement \n'); 35 | // #endregion documentation-snippet 36 | 37 | console.dir(statement, { depth: null, colors: true }); 38 | -------------------------------------------------------------------------------- /examples/nodejs/common/streamToList.ts: -------------------------------------------------------------------------------- 1 | import { BakerId, BlockHash, streamToList } from '@concordium/web-sdk'; 2 | import { ConcordiumGRPCNodeClient } from '@concordium/web-sdk/nodejs'; 3 | import { credentials } from '@grpc/grpc-js'; 4 | import meow from 'meow'; 5 | 6 | import { parseEndpoint } from '../shared/util.js'; 7 | 8 | const cli = meow( 9 | ` 10 | Usage 11 | $ yarn run-example [options] 12 | 13 | Options 14 | --help, Displays this message 15 | --block, -b A block to query from, defaults to last final block 16 | --endpoint, -e Specify endpoint of the form "address:port", defaults to localhost:20000 17 | `, 18 | { 19 | importMeta: import.meta, 20 | flags: { 21 | block: { 22 | type: 'string', 23 | alias: 'b', 24 | default: '', // This defaults to LastFinal 25 | }, 26 | endpoint: { 27 | type: 'string', 28 | alias: 'e', 29 | default: 'localhost:20000', 30 | }, 31 | }, 32 | } 33 | ); 34 | 35 | const [address, port] = parseEndpoint(cli.flags.endpoint); 36 | const client = new ConcordiumGRPCNodeClient(address, Number(port), credentials.createInsecure()); 37 | 38 | /** 39 | * This example shows how the streamToList function can be used. Note that if 40 | * used on an infinite stream (like getBlocks), then it will never terminate. 41 | */ 42 | 43 | async () => { 44 | const blockHash = cli.flags.block === undefined ? undefined : BlockHash.fromHexString(cli.flags.block); 45 | 46 | const bakerIds: AsyncIterable = client.getBakerList(blockHash); 47 | 48 | const bakerList = await streamToList(bakerIds); 49 | 50 | console.log(bakerList[0]); 51 | }; 52 | -------------------------------------------------------------------------------- /examples/nodejs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@concordium/examples", 3 | "private": true, 4 | "type": "module", 5 | "imports": { 6 | "#ed25519": { 7 | "node": "./shims/ed25519.node.ts", 8 | "default": "@noble/ed25519" 9 | } 10 | }, 11 | "dependencies": { 12 | "@concordium/ccd-js-gen": "workspace:^", 13 | "@concordium/web-sdk": "workspace:^", 14 | "@grpc/grpc-js": "^1.3.4", 15 | "@noble/ed25519": "^2.0.0", 16 | "buffer": "^6.0.3", 17 | "meow": "11.0", 18 | "node-fetch": "^3.3.2" 19 | }, 20 | "devDependencies": { 21 | "@types/node": "^20.12.13", 22 | "eslint": "8", 23 | "tsx": "^4.19.2", 24 | "typescript": "^5.2.2" 25 | }, 26 | "scripts": { 27 | "lint": "eslint . --cache --ext ts,tsx --report-unused-disable-directives --max-warnings 0", 28 | "lint-fix": "yarn lint --fix", 29 | "prettier": "prettier . --ignore-path ../../.gitignore --ignore-path ../../.prettierignore --ignore-path .gitignore", 30 | "fmt": "yarn prettier --write", 31 | "fmt-check": "yarn prettier --check", 32 | "build": "tsc --noEmit", 33 | "run-example": "tsx" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /examples/nodejs/shared/util.ts: -------------------------------------------------------------------------------- 1 | import { AccountAddress, ContractAddress } from '@concordium/web-sdk'; 2 | 3 | export const parseAddress = (input: string): AccountAddress.Type | ContractAddress.Type => { 4 | if (!input.includes(',')) { 5 | return AccountAddress.fromBase58(input); 6 | } 7 | 8 | const [i, si] = input.split(','); 9 | const index = parseInt(i); 10 | const subindex = parseInt(si); 11 | if (isNaN(index) || isNaN(subindex)) { 12 | throw new Error('Invalid address'); 13 | } 14 | return ContractAddress.create(index, subindex); 15 | }; 16 | 17 | // Regular expression for matching the scheme prefix of a URL. 18 | const schemeRegex = /^(\w+):\/\//; 19 | 20 | /** 21 | * Parse endpoint information from a string, such as 'http://my-concordium-node:20000' 22 | * @param endpoint String with information of an endpoint. 23 | * @returns Triple with ['
', , '']. 24 | */ 25 | export const parseEndpoint = (endpoint: string): [string, number, string | undefined] => { 26 | const result = schemeRegex.exec(endpoint); 27 | const matched = result?.[0]; 28 | const scheme = result?.[1]; 29 | 30 | const noSchemeEndpoint = endpoint.substring(matched?.length ?? 0); 31 | 32 | // Split endpoint on last colon 33 | const lastColonIndex = noSchemeEndpoint.lastIndexOf(':'); 34 | const address = noSchemeEndpoint.substring(0, lastColonIndex); 35 | const port = Number(noSchemeEndpoint.substring(lastColonIndex + 1)); 36 | 37 | return [address, port, scheme]; 38 | }; 39 | -------------------------------------------------------------------------------- /examples/nodejs/shims/ed25519.node.ts: -------------------------------------------------------------------------------- 1 | // To add support for node versions <19. 2 | // From https://www.npmjs.com/package/@noble/ed25519#usage 3 | import { webcrypto } from 'node:crypto'; 4 | 5 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 6 | // @ts-ignore 7 | if (!globalThis.crypto) globalThis.crypto = webcrypto; 8 | 9 | export * from '@noble/ed25519'; 10 | -------------------------------------------------------------------------------- /examples/nodejs/tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["./**/*.ts"] 3 | } 4 | -------------------------------------------------------------------------------- /examples/nodejs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "ts-node/node16/tsconfig.json", 3 | "ts-node": { 4 | "files": true, 5 | "esm": true 6 | }, 7 | "compilerOptions": { 8 | "esModuleInterop": true, 9 | "lib": ["esnext"], 10 | "baseUrl": ".", 11 | "module": "NodeNext", 12 | "moduleResolution": "NodeNext", 13 | "target": "es2020" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/reactnative/.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /examples/reactnative/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | ios/.xcode.env.local 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | *.hprof 33 | .cxx/ 34 | *.keystore 35 | !debug.keystore 36 | 37 | # node.js 38 | # 39 | node_modules/ 40 | npm-debug.log 41 | yarn-error.log 42 | 43 | # fastlane 44 | # 45 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 46 | # screenshots whenever they are needed. 47 | # For more information about the recommended setup visit: 48 | # https://docs.fastlane.tools/best-practices/source-control/ 49 | 50 | **/fastlane/report.xml 51 | **/fastlane/Preview.html 52 | **/fastlane/screenshots 53 | **/fastlane/test_output 54 | 55 | # Bundle artifact 56 | *.jsbundle 57 | 58 | # Ruby / CocoaPods 59 | /ios/Pods/ 60 | /vendor/bundle/ 61 | 62 | # Temporary files created by Metro to check the health of the file watcher 63 | .metro-health-check* 64 | 65 | # testing 66 | /coverage 67 | -------------------------------------------------------------------------------- /examples/reactnative/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /examples/reactnative/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby ">= 2.6.10" 5 | 6 | gem 'cocoapods', '~> 1.13' 7 | gem 'activesupport', '>= 6.1.7.3', '< 7.1.0' 8 | -------------------------------------------------------------------------------- /examples/reactnative/__tests__/App.test.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | // Note: import explicitly to use the types shiped with jest. 5 | import { it } from '@jest/globals'; 6 | import React from 'react'; 7 | import 'react-native'; 8 | // Note: test renderer must be required after react-native. 9 | import * as renderer from 'react-test-renderer'; 10 | 11 | import App from '../App'; 12 | 13 | it('renders correctly', () => { 14 | renderer.create(); 15 | }); 16 | -------------------------------------------------------------------------------- /examples/reactnative/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/reactnative/android/app/debug.keystore -------------------------------------------------------------------------------- /examples/reactnative/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /examples/reactnative/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/reactnative/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /examples/reactnative/android/app/src/main/java/com/reactnative/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.reactnative; 2 | 3 | import com.facebook.react.ReactActivity; 4 | import com.facebook.react.ReactActivityDelegate; 5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; 6 | import com.facebook.react.defaults.DefaultReactActivityDelegate; 7 | 8 | public class MainActivity extends ReactActivity { 9 | 10 | /** 11 | * Returns the name of the main component registered from JavaScript. This is used to schedule 12 | * rendering of the component. 13 | */ 14 | @Override 15 | protected String getMainComponentName() { 16 | return "reactnative"; 17 | } 18 | 19 | /** 20 | * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link 21 | * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React 22 | * (aka React 18) with two boolean flags. 23 | */ 24 | @Override 25 | protected ReactActivityDelegate createReactActivityDelegate() { 26 | return new DefaultReactActivityDelegate( 27 | this, 28 | getMainComponentName(), 29 | // If you opted-in for the New Architecture, we enable the Fabric Renderer. 30 | DefaultNewArchitectureEntryPoint.getFabricEnabled()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/reactnative/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/reactnative/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/reactnative/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/reactnative/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/reactnative/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/reactnative/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/reactnative/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/reactnative/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/reactnative/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/reactnative/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/reactnative/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/reactnative/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/reactnative/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/reactnative/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/reactnative/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/reactnative/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/reactnative/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/reactnative/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/reactnative/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/reactnative/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/reactnative/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | reactnative 3 | 4 | -------------------------------------------------------------------------------- /examples/reactnative/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/reactnative/android/app/src/release/java/com/reactnative/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.reactnative; 8 | 9 | import android.content.Context; 10 | import com.facebook.react.ReactInstanceManager; 11 | 12 | /** 13 | * Class responsible of loading Flipper inside your React Native application. This is the release 14 | * flavor of it so it's empty as we don't want to load Flipper. 15 | */ 16 | public class ReactNativeFlipper { 17 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 18 | // Do nothing as we don't want to initialize Flipper on Release. 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/reactnative/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | allprojects { 4 | project.pluginManager.withPlugin("com.facebook.react") { 5 | react { 6 | reactNativeDir = rootProject.file("../../../node_modules/react-native/") 7 | codegenDir = rootProject.file("../../../node_modules/react-native-codegen/") 8 | } 9 | } 10 | } 11 | 12 | buildscript { 13 | ext { 14 | buildToolsVersion = "33.0.0" 15 | minSdkVersion = 21 16 | compileSdkVersion = 33 17 | targetSdkVersion = 33 18 | 19 | // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP. 20 | ndkVersion = "23.1.7779620" 21 | } 22 | repositories { 23 | google() 24 | mavenCentral() 25 | } 26 | dependencies { 27 | classpath("com.android.tools.build:gradle") 28 | classpath("com.facebook.react:react-native-gradle-plugin") 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /examples/reactnative/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/reactnative/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /examples/reactnative/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.1-all.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /examples/reactnative/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'reactnative' 2 | apply from: file("../../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | includeBuild('../../../node_modules/@react-native/gradle-plugin') 5 | -------------------------------------------------------------------------------- /examples/reactnative/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactnative", 3 | "displayName": "reactnative" 4 | } 5 | -------------------------------------------------------------------------------- /examples/reactnative/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /examples/reactnative/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | // #region documentation-snippet 5 | import { AppRegistry } from 'react-native'; 6 | 7 | import App from './App'; 8 | import { name as appName } from './app.json'; 9 | // Polyfill must come before any reference to @concordium/web-sdk. 10 | // In this case, that means before importing ./App.tsx 11 | import './polyfill'; 12 | 13 | AppRegistry.registerComponent(appName, () => App); 14 | // #endregion documentation-snippet 15 | -------------------------------------------------------------------------------- /examples/reactnative/ios/.xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /examples/reactnative/ios/reactnative.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/reactnative/ios/reactnative.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /examples/reactnative/ios/reactnative.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/reactnative/ios/reactnative.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/reactnative/ios/reactnative.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /examples/reactnative/ios/reactnative/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : RCTAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /examples/reactnative/ios/reactnative/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import 4 | 5 | @implementation AppDelegate 6 | 7 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 8 | { 9 | self.moduleName = @"reactnative"; 10 | // You can add your custom initial props in the dictionary below. 11 | // They will be passed down to the ViewController used by React Native. 12 | self.initialProps = @{}; 13 | 14 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 15 | } 16 | 17 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 18 | { 19 | #if DEBUG 20 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; 21 | #else 22 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 23 | #endif 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /examples/reactnative/ios/reactnative/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "idiom": "iphone", 5 | "scale": "2x", 6 | "size": "20x20" 7 | }, 8 | { 9 | "idiom": "iphone", 10 | "scale": "3x", 11 | "size": "20x20" 12 | }, 13 | { 14 | "idiom": "iphone", 15 | "scale": "2x", 16 | "size": "29x29" 17 | }, 18 | { 19 | "idiom": "iphone", 20 | "scale": "3x", 21 | "size": "29x29" 22 | }, 23 | { 24 | "idiom": "iphone", 25 | "scale": "2x", 26 | "size": "40x40" 27 | }, 28 | { 29 | "idiom": "iphone", 30 | "scale": "3x", 31 | "size": "40x40" 32 | }, 33 | { 34 | "idiom": "iphone", 35 | "scale": "2x", 36 | "size": "60x60" 37 | }, 38 | { 39 | "idiom": "iphone", 40 | "scale": "3x", 41 | "size": "60x60" 42 | }, 43 | { 44 | "idiom": "ios-marketing", 45 | "scale": "1x", 46 | "size": "1024x1024" 47 | } 48 | ], 49 | "info": { 50 | "author": "xcode", 51 | "version": 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /examples/reactnative/ios/reactnative/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "version": 1, 4 | "author": "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/reactnative/ios/reactnative/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | reactnative 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(CURRENT_PROJECT_VERSION) 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSExceptionDomains 30 | 31 | localhost 32 | 33 | NSExceptionAllowsInsecureHTTPLoads 34 | 35 | 36 | 37 | 38 | NSLocationWhenInUseUsageDescription 39 | 40 | UILaunchStoryboardName 41 | LaunchScreen 42 | UIRequiredDeviceCapabilities 43 | 44 | armv7 45 | 46 | UISupportedInterfaceOrientations 47 | 48 | UIInterfaceOrientationPortrait 49 | UIInterfaceOrientationLandscapeLeft 50 | UIInterfaceOrientationLandscapeRight 51 | 52 | UIViewControllerBasedStatusBarAppearance 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /examples/reactnative/ios/reactnative/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | @autoreleasepool { 8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/reactnative/ios/reactnativeTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /examples/reactnative/jest.config.js: -------------------------------------------------------------------------------- 1 | const esModules = ['@noble/ed25519', 'react-native', '@react-native'].join('|'); 2 | 3 | module.exports = { 4 | preset: 'react-native', 5 | setupFiles: ['./jest/setup.ts'], 6 | transformIgnorePatterns: [`node_modules/(?!${esModules})`], 7 | }; 8 | -------------------------------------------------------------------------------- /examples/reactnative/jest/setup.ts: -------------------------------------------------------------------------------- 1 | (global as any).self = global; 2 | 3 | export {}; 4 | -------------------------------------------------------------------------------- /examples/reactnative/metro.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); 3 | 4 | /** 5 | * Metro configuration 6 | * https://facebook.github.io/metro/docs/configuration 7 | * 8 | * @type {import('metro-config').MetroConfig} 9 | */ 10 | const config = { 11 | resolver: { 12 | unstable_enableSymlinks: true, // This is only needed due to @concordium/web-sdk being symlinked. 13 | unstable_enablePackageExports: true, // Enables referencing by "exports" field in package.json 14 | }, 15 | watchFolders: [ 16 | path.resolve(__dirname, '../../node_modules'), 17 | path.resolve(__dirname, '../../node_modules/@concordium/web-sdk'), 18 | ], 19 | }; 20 | 21 | module.exports = mergeConfig(getDefaultConfig(__dirname), config); 22 | -------------------------------------------------------------------------------- /examples/reactnative/polyfill.ts: -------------------------------------------------------------------------------- 1 | // #region documentation-snippet 2 | // Requires peer dependency `text-encoding` 3 | import '@azure/core-asynciterator-polyfill'; 4 | import '@stardazed/streams-polyfill'; 5 | // @ts-ignore 6 | import { polyfill as polyfillCrypto } from 'react-native-polyfill-globals/src/crypto'; 7 | // @ts-ignore 8 | import { polyfill as polyfillEncoding } from 'react-native-polyfill-globals/src/encoding'; 9 | 10 | // Requires peer dependency `react-native-get-random-values` 11 | 12 | polyfillEncoding(); 13 | polyfillCrypto(); 14 | // #endregion documentation-snippet 15 | -------------------------------------------------------------------------------- /examples/reactnative/tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["./*.ts", "./*.tsx", "./*.js", "jest", "__tests__"] 4 | } 5 | -------------------------------------------------------------------------------- /examples/reactnative/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/react-native/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /examples/wallet-connection/contractupdate/.dockerignore: -------------------------------------------------------------------------------- 1 | *ignore 2 | Dockerfile 3 | docker-compose.yaml 4 | *.md 5 | /build 6 | /node_modules 7 | -------------------------------------------------------------------------------- /examples/wallet-connection/contractupdate/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /examples/wallet-connection/contractupdate/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | ARG build_image="node:16-slim" 4 | FROM ${build_image} AS build 5 | WORKDIR /build 6 | # Note that 'yarn.lock' isn't included as it resides in the root of the repository. 7 | COPY package.json . 8 | RUN yarn install 9 | COPY . . 10 | RUN yarn build 11 | 12 | FROM httpd:2-alpine 13 | COPY --from=build /build/build /usr/local/apache2/htdocs 14 | -------------------------------------------------------------------------------- /examples/wallet-connection/contractupdate/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | contractupdate: 4 | image: ${CONTRACTUPDATE_IMAGE-concordium-dapp-contractupdate:test} 5 | build: . 6 | ports: 7 | - '${CONTRACTUPDATE_PORT-8080}:80' 8 | -------------------------------------------------------------------------------- /examples/wallet-connection/contractupdate/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "concordium-dapp-contractupdate", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@concordium/react-components": "workspace:^", 7 | "@concordium/web-sdk": "workspace:^", 8 | "@walletconnect/types": "^2.13.1", 9 | "bootstrap": "^5.2.3", 10 | "buffer": "^6.0.3", 11 | "neverthrow": "^6.0.0", 12 | "react": "^18.2.0", 13 | "react-bootstrap": "^2.7.0", 14 | "react-bootstrap-icons": "^1.10.2", 15 | "react-dom": "^18.2.0", 16 | "stream": "npm:stream-browserify@3.0.0", 17 | "web-vitals": "^2.1.0" 18 | }, 19 | "devDependencies": { 20 | "@types/is-base64": "^1.1.1", 21 | "@types/node": "^16.7.13", 22 | "@types/react": "^18.0.0", 23 | "@types/react-dom": "^18.0.0", 24 | "eslint": "8", 25 | "prettier": "^3.2.5", 26 | "react-scripts": "^5.0.1", 27 | "typescript": "^5.2.2" 28 | }, 29 | "scripts": { 30 | "lint": "eslint . --cache --ext ts,tsx --report-unused-disable-directives --max-warnings 0", 31 | "lint-fix": "yarn lint --fix", 32 | "prettier": "prettier . --ignore-path ../../.gitignore --ignore-path ../../.prettierignore --ignore-path .gitignore", 33 | "fmt": "yarn prettier --write", 34 | "fmt-check": "yarn prettier --check", 35 | "start": "react-scripts start", 36 | "build": "react-scripts build", 37 | "test": "react-scripts test", 38 | "eject": "react-scripts eject" 39 | }, 40 | "browserslist": { 41 | "production": [ 42 | ">0.2%", 43 | "not dead", 44 | "not op_mini all" 45 | ], 46 | "development": [ 47 | "last 1 chrome version", 48 | "last 1 firefox version", 49 | "last 1 safari version" 50 | ] 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /examples/wallet-connection/contractupdate/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/wallet-connection/contractupdate/public/favicon.ico -------------------------------------------------------------------------------- /examples/wallet-connection/contractupdate/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Sample Concordium dApp 10 | 11 | 12 | 13 |

14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/wallet-connection/contractupdate/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/wallet-connection/contractupdate/public/logo192.png -------------------------------------------------------------------------------- /examples/wallet-connection/contractupdate/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/wallet-connection/contractupdate/public/logo512.png -------------------------------------------------------------------------------- /examples/wallet-connection/contractupdate/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Sample dApp", 3 | "name": "Sample Concordium dApp", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /examples/wallet-connection/contractupdate/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /examples/wallet-connection/contractupdate/src/ContractDetails.tsx: -------------------------------------------------------------------------------- 1 | import { Info } from '@concordium/react-components'; 2 | import { Alert, Col, Row } from 'react-bootstrap'; 3 | 4 | interface Props { 5 | contract: Info; 6 | } 7 | 8 | export function ContractDetails({ contract }: Props) { 9 | return ( 10 | 11 | 12 | Name: 13 | 14 | {contract.name} 15 | 16 | 17 | 18 | Index: 19 | 20 | {contract.index.toString()} 21 | 22 | 23 | 24 | Owner: 25 | 26 | {contract.owner.address} 27 | 28 | 29 | 30 | Balance: 31 | {contract.amount.microCcdAmount.toString()} μCCD 32 | 33 | 34 | Methods: 35 | {contract.methods.join(', ')} 36 | 37 | 38 | Platform: 39 | v{contract.version} 40 | 41 | 42 | ); 43 | } 44 | -------------------------------------------------------------------------------- /examples/wallet-connection/contractupdate/src/NetworkSelector.tsx: -------------------------------------------------------------------------------- 1 | import { Network } from '@concordium/react-components'; 2 | import { useCallback } from 'react'; 3 | import { Dropdown } from 'react-bootstrap'; 4 | 5 | interface Props { 6 | selected: Network; 7 | options: Array; 8 | select: (n: Network) => void; 9 | } 10 | 11 | export function NetworkSelector({ selected, options, select }: Props) { 12 | const onSelect = useCallback((key: any) => select(options[key as number]), [options, select]); 13 | return ( 14 | 15 | 16 | Network: {selected.name} 17 | 18 | 19 | {options.map((n, idx) => ( 20 | 21 | {n.name} 22 | 23 | ))} 24 | 25 | 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /examples/wallet-connection/contractupdate/src/WalletConnectorButton.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | ConnectorType, 3 | WalletConnection, 4 | WalletConnectionProps, 5 | useWalletConnectorSelector, 6 | } from '@concordium/react-components'; 7 | import React from 'react'; 8 | import { Button } from 'react-bootstrap'; 9 | 10 | interface Props extends WalletConnectionProps { 11 | connection: WalletConnection | undefined; 12 | connectorType: ConnectorType; 13 | connectorName: string; 14 | } 15 | 16 | export function WalletConnectorButton(props: Props) { 17 | const { connection, connectorType, connectorName } = props; 18 | const { isSelected, isConnected, isDisabled, select } = useWalletConnectorSelector( 19 | connectorType, 20 | connection, 21 | props 22 | ); 23 | 24 | const verb = isConnected ? 'Disconnect' : isSelected ? 'Using' : 'Use'; 25 | return ( 26 | 34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /examples/wallet-connection/contractupdate/src/config.ts: -------------------------------------------------------------------------------- 1 | import { 2 | BrowserWalletConnector, 3 | CONCORDIUM_WALLET_CONNECT_PROJECT_ID, 4 | WalletConnectConnector, 5 | WalletConnectEvent, 6 | WalletConnectMethod, 7 | WalletConnectNamespaceConfig, 8 | ephemeralConnectorType, 9 | } from '@concordium/react-components'; 10 | import { SignClientTypes } from '@walletconnect/types'; 11 | 12 | const WALLET_CONNECT_OPTS: SignClientTypes.Options = { 13 | projectId: CONCORDIUM_WALLET_CONNECT_PROJECT_ID, 14 | metadata: { 15 | name: 'Contract Update', 16 | description: 'Example dApp for the performing an update on a contract.', 17 | url: '#', 18 | icons: ['https://walletconnect.com/walletconnect-logo.png'], 19 | }, 20 | }; 21 | 22 | const WALLET_CONNECT_NS_CONFIG: WalletConnectNamespaceConfig = { 23 | methods: [WalletConnectMethod.SignAndSendTransaction], 24 | events: [WalletConnectEvent.AccountsChanged, WalletConnectEvent.ChainChanged], 25 | }; 26 | 27 | export const BROWSER_WALLET = ephemeralConnectorType(BrowserWalletConnector.create); 28 | export const WALLET_CONNECT = ephemeralConnectorType((delegate, network) => 29 | WalletConnectConnector.create(WALLET_CONNECT_OPTS, delegate, network, WALLET_CONNECT_NS_CONFIG) 30 | ); 31 | -------------------------------------------------------------------------------- /examples/wallet-connection/contractupdate/src/index.tsx: -------------------------------------------------------------------------------- 1 | import 'bootstrap/dist/css/bootstrap.min.css'; 2 | import React from 'react'; 3 | import ReactDOM from 'react-dom/client'; 4 | 5 | import Root from './Root'; 6 | import reportWebVitals from './reportWebVitals'; 7 | 8 | const root = ReactDOM.createRoot(document.getElementById('root')!); 9 | root.render( 10 | 11 | 12 | 13 | ); 14 | 15 | // If you want to start measuring performance in your app, pass a function 16 | // to log results (for example: reportWebVitals(console.log)) 17 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 18 | reportWebVitals(); 19 | -------------------------------------------------------------------------------- /examples/wallet-connection/contractupdate/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/wallet-connection/contractupdate/src/reportWebVitals.ts: -------------------------------------------------------------------------------- 1 | import { ReportHandler } from 'web-vitals'; 2 | 3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => { 4 | if (onPerfEntry && onPerfEntry instanceof Function) { 5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 6 | getCLS(onPerfEntry); 7 | getFID(onPerfEntry); 8 | getFCP(onPerfEntry); 9 | getLCP(onPerfEntry); 10 | getTTFB(onPerfEntry); 11 | }); 12 | } 13 | }; 14 | 15 | export default reportWebVitals; 16 | -------------------------------------------------------------------------------- /examples/wallet-connection/contractupdate/src/util.ts: -------------------------------------------------------------------------------- 1 | export function setErrorString(setError: (err: string) => void) { 2 | return (err: any) => setError(errorString(err)); 3 | } 4 | 5 | export function errorString(err: any): string { 6 | return (err as Error).message || (err as string); 7 | } 8 | -------------------------------------------------------------------------------- /examples/wallet-connection/contractupdate/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "esModuleInterop": true, 8 | "allowSyntheticDefaultImports": true, 9 | "strict": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react-jsx" 18 | }, 19 | "include": ["./src"] 20 | } 21 | -------------------------------------------------------------------------------- /examples/wallet-connection/proofs/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /examples/wallet-connection/proofs/.prettierignore: -------------------------------------------------------------------------------- 1 | build/ 2 | -------------------------------------------------------------------------------- /examples/wallet-connection/proofs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "concordium-dapp-request-verifiable-presentation", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@concordium/react-components": "workspace:^", 7 | "@concordium/web-sdk": "workspace:^", 8 | "@types/node": "^16.18.16", 9 | "@types/react": "^18.0.28", 10 | "@types/react-dom": "^18.0.11", 11 | "@walletconnect/types": "^2.13.1", 12 | "bootstrap": "^5.2.3", 13 | "eslint": "8", 14 | "react": "^18.2.0", 15 | "react-bootstrap": "^2.7.2", 16 | "react-dom": "^18.2.0", 17 | "react-scripts": "^5.0.1", 18 | "typescript": "^5.2.2" 19 | }, 20 | "scripts": { 21 | "lint": "eslint . --cache --ext ts,tsx --report-unused-disable-directives --max-warnings 0", 22 | "lint-fix": "yarn lint --fix", 23 | "prettier": "prettier . --ignore-path ../../.gitignore --ignore-path ../../.prettierignore --ignore-path .gitignore", 24 | "fmt": "yarn prettier --write", 25 | "fmt-check": "yarn prettier --check", 26 | "start": "react-scripts start", 27 | "build": "react-scripts build", 28 | "test": "react-scripts test", 29 | "eject": "react-scripts eject" 30 | }, 31 | "browserslist": { 32 | "production": [ 33 | ">0.2%", 34 | "not dead", 35 | "not op_mini all" 36 | ], 37 | "development": [ 38 | "last 1 chrome version", 39 | "last 1 firefox version", 40 | "last 1 safari version" 41 | ] 42 | }, 43 | "devDependencies": { 44 | "prettier": "^3.2.5" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /examples/wallet-connection/proofs/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/wallet-connection/proofs/public/favicon.ico -------------------------------------------------------------------------------- /examples/wallet-connection/proofs/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Identity proofs | Sample Concordium dApp 10 | 11 | 12 | 13 |
14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/wallet-connection/proofs/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/wallet-connection/proofs/public/logo192.png -------------------------------------------------------------------------------- /examples/wallet-connection/proofs/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/wallet-connection/proofs/public/logo512.png -------------------------------------------------------------------------------- /examples/wallet-connection/proofs/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Sample dApp", 3 | "name": "Sample Concordium dApp", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /examples/wallet-connection/proofs/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /examples/wallet-connection/proofs/src/WalletConnectorButton.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | ConnectorType, 3 | WalletConnection, 4 | WalletConnectionProps, 5 | useWalletConnectorSelector, 6 | } from '@concordium/react-components'; 7 | import React from 'react'; 8 | import { Button } from 'react-bootstrap'; 9 | 10 | interface Props extends WalletConnectionProps { 11 | connection: WalletConnection | undefined; 12 | connectorType: ConnectorType; 13 | connectorName: string; 14 | } 15 | 16 | export function WalletConnectorButton(props: Props) { 17 | const { connection, connectorType, connectorName } = props; 18 | const { isSelected, isConnected, isDisabled, select } = useWalletConnectorSelector( 19 | connectorType, 20 | connection, 21 | props 22 | ); 23 | 24 | const verb = isConnected ? 'Disconnect' : isSelected ? 'Using' : 'Use'; 25 | return ( 26 | 34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /examples/wallet-connection/proofs/src/config.ts: -------------------------------------------------------------------------------- 1 | import { 2 | BrowserWalletConnector, 3 | CONCORDIUM_WALLET_CONNECT_PROJECT_ID, 4 | WalletConnectConnector, 5 | WalletConnectEvent, 6 | WalletConnectMethod, 7 | WalletConnectNamespaceConfig, 8 | ephemeralConnectorType, 9 | } from '@concordium/react-components'; 10 | import { SignClientTypes } from '@walletconnect/types'; 11 | 12 | const WALLET_CONNECT_OPTS: SignClientTypes.Options = { 13 | projectId: CONCORDIUM_WALLET_CONNECT_PROJECT_ID, 14 | metadata: { 15 | name: 'Identity proof', 16 | description: 'Example dApp for requesting an identity proof.', 17 | url: '#', 18 | icons: ['https://walletconnect.com/walletconnect-logo.png'], 19 | }, 20 | }; 21 | 22 | const WALLET_CONNECT_SCOPE: WalletConnectNamespaceConfig = { 23 | methods: [WalletConnectMethod.RequestVerifiablePresentation], 24 | events: [WalletConnectEvent.AccountsChanged, WalletConnectEvent.ChainChanged], 25 | }; 26 | 27 | export const BROWSER_WALLET = ephemeralConnectorType(BrowserWalletConnector.create); 28 | export const WALLET_CONNECT = ephemeralConnectorType((delegate, network) => 29 | WalletConnectConnector.create(WALLET_CONNECT_OPTS, delegate, network, WALLET_CONNECT_SCOPE) 30 | ); 31 | -------------------------------------------------------------------------------- /examples/wallet-connection/proofs/src/index.tsx: -------------------------------------------------------------------------------- 1 | import 'bootstrap/dist/css/bootstrap.min.css'; 2 | import React from 'react'; 3 | import ReactDOM from 'react-dom/client'; 4 | 5 | import App from './App'; 6 | 7 | const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); 8 | root.render( 9 | 10 | 11 | 12 | ); 13 | -------------------------------------------------------------------------------- /examples/wallet-connection/proofs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "esModuleInterop": true, 8 | "allowSyntheticDefaultImports": true, 9 | "strict": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react-jsx" 18 | }, 19 | "include": ["./src"] 20 | } 21 | -------------------------------------------------------------------------------- /examples/wallet-connection/sign-message/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /examples/wallet-connection/sign-message/.prettierignore: -------------------------------------------------------------------------------- 1 | build/ 2 | -------------------------------------------------------------------------------- /examples/wallet-connection/sign-message/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "concordium-dapp-sign-message", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@concordium/react-components": "workspace:^", 7 | "@concordium/web-sdk": "workspace:^", 8 | "@types/node": "^16.18.16", 9 | "@types/react": "^18.0.28", 10 | "@types/react-dom": "^18.0.11", 11 | "@walletconnect/types": "^2.13.1", 12 | "bootstrap": "^5.2.3", 13 | "neverthrow": "^6.2.1", 14 | "react": "^18.2.0", 15 | "react-bootstrap": "^2.7.2", 16 | "react-dom": "^18.2.0", 17 | "react-scripts": "^5.0.1", 18 | "typescript": "^5.2.2" 19 | }, 20 | "scripts": { 21 | "lint": "eslint . --cache --ext ts,tsx --report-unused-disable-directives --max-warnings 0", 22 | "lint-fix": "yarn lint --fix", 23 | "prettier": "prettier . --ignore-path ../../.gitignore --ignore-path ../../.prettierignore --ignore-path .gitignore", 24 | "fmt": "yarn prettier --write", 25 | "fmt-check": "yarn prettier --check", 26 | "start": "react-scripts start", 27 | "build": "react-scripts build", 28 | "test": "react-scripts test", 29 | "eject": "react-scripts eject" 30 | }, 31 | "browserslist": { 32 | "production": [ 33 | ">0.2%", 34 | "not dead", 35 | "not op_mini all" 36 | ], 37 | "development": [ 38 | "last 1 chrome version", 39 | "last 1 firefox version", 40 | "last 1 safari version" 41 | ] 42 | }, 43 | "devDependencies": { 44 | "eslint": "8", 45 | "prettier": "^3.2.5" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /examples/wallet-connection/sign-message/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/wallet-connection/sign-message/public/favicon.ico -------------------------------------------------------------------------------- /examples/wallet-connection/sign-message/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Sign Message | Sample Concordium dApp 10 | 11 | 12 | 13 |
14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/wallet-connection/sign-message/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/wallet-connection/sign-message/public/logo192.png -------------------------------------------------------------------------------- /examples/wallet-connection/sign-message/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/examples/wallet-connection/sign-message/public/logo512.png -------------------------------------------------------------------------------- /examples/wallet-connection/sign-message/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Sample dApp", 3 | "name": "Sample Concordium dApp", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /examples/wallet-connection/sign-message/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /examples/wallet-connection/sign-message/src/WalletConnectorButton.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | ConnectorType, 3 | WalletConnection, 4 | WalletConnectionProps, 5 | useWalletConnectorSelector, 6 | } from '@concordium/react-components'; 7 | import React from 'react'; 8 | import { Button } from 'react-bootstrap'; 9 | 10 | interface Props extends WalletConnectionProps { 11 | connection: WalletConnection | undefined; 12 | connectorType: ConnectorType; 13 | connectorName: string; 14 | } 15 | 16 | export function WalletConnectorButton(props: Props) { 17 | const { connection, connectorType, connectorName } = props; 18 | const { isSelected, isConnected, isDisabled, select } = useWalletConnectorSelector( 19 | connectorType, 20 | connection, 21 | props 22 | ); 23 | 24 | const verb = isConnected ? 'Disconnect' : isSelected ? 'Using' : 'Use'; 25 | return ( 26 | 34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /examples/wallet-connection/sign-message/src/config.ts: -------------------------------------------------------------------------------- 1 | import { 2 | BrowserWalletConnector, 3 | CONCORDIUM_WALLET_CONNECT_PROJECT_ID, 4 | WalletConnectConnector, 5 | WalletConnectEvent, 6 | WalletConnectMethod, 7 | WalletConnectNamespaceConfig, 8 | ephemeralConnectorType, 9 | } from '@concordium/react-components'; 10 | import { SignClientTypes } from '@walletconnect/types'; 11 | 12 | const WALLET_CONNECT_OPTS: SignClientTypes.Options = { 13 | projectId: CONCORDIUM_WALLET_CONNECT_PROJECT_ID, 14 | metadata: { 15 | name: 'Sign Message', 16 | description: 'Example dApp for signing an arbitrary message.', 17 | url: '#', 18 | icons: ['https://walletconnect.com/walletconnect-logo.png'], 19 | }, 20 | }; 21 | 22 | const WALLET_CONNECT_SCOPE: WalletConnectNamespaceConfig = { 23 | methods: [WalletConnectMethod.SignMessage], 24 | events: [WalletConnectEvent.AccountsChanged, WalletConnectEvent.ChainChanged], 25 | }; 26 | 27 | export const BROWSER_WALLET = ephemeralConnectorType(BrowserWalletConnector.create); 28 | export const WALLET_CONNECT = ephemeralConnectorType((delegate, network) => 29 | WalletConnectConnector.create(WALLET_CONNECT_OPTS, delegate, network, WALLET_CONNECT_SCOPE) 30 | ); 31 | -------------------------------------------------------------------------------- /examples/wallet-connection/sign-message/src/index.tsx: -------------------------------------------------------------------------------- 1 | import 'bootstrap/dist/css/bootstrap.min.css'; 2 | import React from 'react'; 3 | import ReactDOM from 'react-dom/client'; 4 | 5 | import App from './App'; 6 | 7 | const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); 8 | root.render( 9 | 10 | 11 | 12 | ); 13 | -------------------------------------------------------------------------------- /examples/wallet-connection/sign-message/src/util.ts: -------------------------------------------------------------------------------- 1 | export function setErrorString(setError: (err: string) => void) { 2 | return (err: any) => setError(errorString(err)); 3 | } 4 | 5 | export function errorString(err: any): string { 6 | return (err as Error).message || (err as string); 7 | } 8 | -------------------------------------------------------------------------------- /examples/wallet-connection/sign-message/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "esModuleInterop": true, 8 | "allowSyntheticDefaultImports": true, 9 | "strict": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react-jsx" 18 | }, 19 | "include": ["./src"] 20 | } 21 | -------------------------------------------------------------------------------- /examples/wallet/README.md: -------------------------------------------------------------------------------- 1 | # Wallet example for web applications 2 | 3 | This example demonstrates how to utilize the Concordium web-sdk to build a web based wallet for interacting with the Concordium blockchain. In particular 4 | it focuses on the creation of identities and accounts, and sending a simple transfer. As it just serves as a simple example everything is in-memory, and 5 | nothing is persisted. 6 | 7 | ## Installing 8 | 9 | From the root of concordium-node-sdk-js you must run 10 | 11 | ```console 12 | yarn install 13 | ``` 14 | 15 | ### Skip building 16 | 17 | An alternative to building all of the packages in the project, you can change the code base to use the builds already published on NPM, note that this might not work for unreleased changes: 18 | 19 | - Remove packages from the workspace i.e remove the line with `"./packages/*",` from `package.json` in the project root. 20 | - Replace `workspace:^` in `package.json` found in this example with `*`: 21 | 22 | ```json 23 | ... 24 | "@concordium/web-sdk": "*", 25 | ``` 26 | 27 | Then run: 28 | 29 | ```shell 30 | yarn workspaces focus @concordium/examples-web-wallet 31 | ``` 32 | 33 | to only install dependencies related to examples. 34 | 35 | ## Running 36 | 37 | When dependencies have been installed, then build and run the example by executing 38 | 39 | ```console 40 | yarn build && yarn start 41 | ``` 42 | 43 | The console will output the location where the example can be accessed. 44 | -------------------------------------------------------------------------------- /examples/wallet/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/wallet/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@concordium/examples-web-wallet", 3 | "private": true, 4 | "packageManager": "yarn@3.2.0", 5 | "dependencies": { 6 | "@concordium/web-sdk": "workspace:^", 7 | "@scure/bip39": "^1.2.1", 8 | "buffer": "^6.0.3", 9 | "react": "18.2.0", 10 | "react-cookie": "^6.1.1", 11 | "react-dom": "^18.1.0", 12 | "react-json-pretty": "^2.2.0", 13 | "react-router-dom": "^6.18.0" 14 | }, 15 | "devDependencies": { 16 | "@types/node": "^20.12.13", 17 | "@types/react": "^18.0.24", 18 | "@types/react-dom": "^18.0.5", 19 | "@vitejs/plugin-react-swc": "^3.4.0", 20 | "eslint": "8", 21 | "ts-node": "10.9", 22 | "typescript": "^5.2.2", 23 | "vite": "^4.5.0", 24 | "vite-plugin-svgr": "^4.1.0", 25 | "vite-plugin-top-level-await": "^1.3.1", 26 | "vite-plugin-wasm": "^3.2.2" 27 | }, 28 | "scripts": { 29 | "build": "tsc && vite build", 30 | "dev": "vite", 31 | "start": "vite preview", 32 | "lint": "eslint . --cache --ext ts,tsx --report-unused-disable-directives --max-warnings 0", 33 | "lint-fix": "yarn lint --fix", 34 | "prettier": "prettier . --ignore-path ../../.gitignore --ignore-path ../../.prettierignore --ignore-path .gitignore", 35 | "fmt": "yarn prettier --write", 36 | "fmt-check": "yarn prettier --check" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /examples/wallet/src/ConfirmIdentity.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { useLocation, useNavigate } from 'react-router-dom'; 3 | 4 | import { identityObjectKey } from './constants'; 5 | import { extractIdentityObjectUrl, fetchIdentity } from './util'; 6 | 7 | export function ConfirmIdentity() { 8 | const location = useLocation(); 9 | const [error, setError] = useState(); 10 | const navigate = useNavigate(); 11 | 12 | useEffect(() => { 13 | const identityObjectUrl = extractIdentityObjectUrl(location.hash); 14 | fetchIdentity(identityObjectUrl) 15 | .then((raw) => { 16 | localStorage.setItem(identityObjectKey, JSON.stringify(raw)); 17 | navigate('/identity'); 18 | }) 19 | .catch(setError); 20 | }, [location.hash]); 21 | 22 | if (error) { 23 | return ( 24 |
25 |

Identity creation failed

26 |
{error}
27 |
28 | ); 29 | } 30 | 31 | return ( 32 | <> 33 |

Identity is not ready yet. Please wait.

34 | 35 | ); 36 | } 37 | -------------------------------------------------------------------------------- /examples/wallet/src/Identity.tsx: -------------------------------------------------------------------------------- 1 | import { AttributeList, IdentityObjectV1 } from '@concordium/web-sdk'; 2 | import React, { useMemo, useState } from 'react'; 3 | 4 | import { CreateAccount } from './CreateAccount'; 5 | import { identityObjectKey } from './constants'; 6 | 7 | function DisplayIdentity({ attributes }: { attributes: AttributeList }) { 8 | return ( 9 |
    10 |
  • 11 | Name: {attributes.chosenAttributes.firstName} {attributes.chosenAttributes.lastName} 12 |
  • 13 |
  • Nationality: {attributes.chosenAttributes.nationality}
  • 14 |
15 | ); 16 | } 17 | 18 | export function Identity() { 19 | const [missingIdentity, setMissingIdentity] = useState(false); 20 | const identity = useMemo(() => { 21 | const identityObjectJson = localStorage.getItem(identityObjectKey); 22 | if (identityObjectJson) { 23 | return JSON.parse(identityObjectJson); 24 | } else { 25 | setMissingIdentity(true); 26 | } 27 | }, []); 28 | 29 | return ( 30 | <> 31 |

Your Concordium identity

32 | {missingIdentity &&

Missing identity in storage

} 33 | {identity && ( 34 | <> 35 | 36 | 37 | 38 | )} 39 | 40 | ); 41 | } 42 | -------------------------------------------------------------------------------- /examples/wallet/src/Index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import { RouterProvider, createBrowserRouter } from 'react-router-dom'; 4 | 5 | import { Account } from './Account'; 6 | import { ConfirmIdentity } from './ConfirmIdentity'; 7 | import { CreateIdentity } from './CreateIdentity'; 8 | import { Identity } from './Identity'; 9 | import { NewIdentity } from './NewIdentity'; 10 | import { RecoverIdentity } from './RecoverIdentity'; 11 | import { SetupSeedPhrase } from './Setup'; 12 | import './index.css'; 13 | 14 | const container = document.getElementById('root'); 15 | 16 | if (!container) { 17 | throw new Error('Expected container DOM node to be defined'); 18 | } 19 | 20 | const router = createBrowserRouter([ 21 | { 22 | path: '/', 23 | element: , 24 | }, 25 | { 26 | path: '/new', 27 | element: , 28 | }, 29 | { 30 | path: '/create', 31 | element: , 32 | }, 33 | { 34 | path: '/confirm-identity', 35 | element: , 36 | }, 37 | { 38 | path: '/identity', 39 | element: , 40 | }, 41 | { 42 | path: '/recover', 43 | element: , 44 | }, 45 | { 46 | path: '/account/:accountAddress', 47 | element: , 48 | }, 49 | ]); 50 | 51 | createRoot(container).render( 52 | 53 | 54 | 55 | ); 56 | -------------------------------------------------------------------------------- /examples/wallet/src/NewIdentity.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useNavigate } from 'react-router-dom'; 3 | 4 | export function NewIdentity() { 5 | const navigate = useNavigate(); 6 | return ( 7 |
8 |

Your Concordium Identity

9 | 10 | 11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /examples/wallet/src/Setup.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { useNavigate } from 'react-router-dom'; 3 | 4 | import { seedPhraseKey } from './constants'; 5 | 6 | /** 7 | * Allow the user to input their seed phrase. The seed phrase will be stored 8 | * in a cookie which is not safe, so only use this with a seed phrase generated 9 | * specifically for testing. 10 | */ 11 | export function SetupSeedPhrase() { 12 | const [seedPhraseWords, setSeedPhraseWords] = useState(); 13 | const navigate = useNavigate(); 14 | 15 | function handleSubmit(event: React.FormEvent) { 16 | event.preventDefault(); 17 | 18 | if (!seedPhraseWords) { 19 | alert('Please input a seed phrase'); 20 | return; 21 | } 22 | 23 | try { 24 | localStorage.setItem(seedPhraseKey, seedPhraseWords); 25 | navigate('/new'); 26 | } catch { 27 | alert('An invalid seed phrase was provided'); 28 | return; 29 | } 30 | } 31 | 32 | return ( 33 |
34 | 42 | 43 |
44 | ); 45 | } 46 | -------------------------------------------------------------------------------- /examples/wallet/src/account-worker.ts: -------------------------------------------------------------------------------- 1 | import { createCredentialTransactionNoSeed } from '@concordium/web-sdk'; 2 | 3 | import { AccountWorkerInput } from './types'; 4 | 5 | self.onmessage = (e: MessageEvent) => { 6 | const credentialTransaction = createCredentialTransactionNoSeed(e.data.credentialInput, e.data.expiry); 7 | self.postMessage(credentialTransaction); 8 | }; 9 | -------------------------------------------------------------------------------- /examples/wallet/src/constants.ts: -------------------------------------------------------------------------------- 1 | import { Network } from '@concordium/web-sdk'; 2 | 3 | export const network: Network = 'Testnet'; 4 | 5 | // Local storage keys 6 | export const seedPhraseKey = 'seed-phrase'; 7 | export const selectedIdentityProviderKey = 'selected-identity-provider'; 8 | export const identityObjectKey = 'identity-object'; 9 | 10 | // The indices of the identity and the credential deployed on the account. 11 | // These are static in this example as we only create a single identity and 12 | // a single credential. 13 | export const identityIndex = 0; 14 | export const credNumber = 0; 15 | 16 | // Connection parameters that determine the node that the wallet 17 | // connects to. 18 | export const nodeAddress = 'https://grpc.testnet.concordium.com'; 19 | export const nodePort = 20000; 20 | 21 | // Base URL for the wallet proxy. 22 | export const walletProxyBaseUrl = 'https://wallet-proxy.testnet.concordium.com'; 23 | 24 | // Base URL for CCDscan. This is used to link to a submitted transaction. 25 | export const ccdscanBaseUrl = 'https://testnet.ccdscan.io'; 26 | -------------------------------------------------------------------------------- /examples/wallet/src/identity-worker.ts: -------------------------------------------------------------------------------- 1 | import { IdentityRequestWithKeysInput, createIdentityRequestWithKeys } from '@concordium/web-sdk'; 2 | 3 | self.onmessage = (e: MessageEvent) => { 4 | const identityRequest = createIdentityRequestWithKeys(e.data); 5 | self.postMessage(identityRequest); 6 | }; 7 | -------------------------------------------------------------------------------- /examples/wallet/src/index.css: -------------------------------------------------------------------------------- 1 | select, 2 | button, 3 | input { 4 | display: block; 5 | } 6 | -------------------------------------------------------------------------------- /examples/wallet/src/recovery-worker.ts: -------------------------------------------------------------------------------- 1 | import { IdentityRecoveryRequestWithKeysInput, createIdentityRecoveryRequestWithKeys } from '@concordium/web-sdk'; 2 | 3 | self.onmessage = (e: MessageEvent) => { 4 | const recoveryRequest = createIdentityRecoveryRequestWithKeys(e.data); 5 | self.postMessage(recoveryRequest); 6 | }; 7 | -------------------------------------------------------------------------------- /examples/wallet/src/types.ts: -------------------------------------------------------------------------------- 1 | import { 2 | CredentialInputNoSeed, 3 | IdentityObjectV1, 4 | IdentityProvider, 5 | TransactionExpiry, 6 | Versioned, 7 | } from '@concordium/web-sdk'; 8 | 9 | export interface IdentityProviderMetaData { 10 | issuanceStart: string; 11 | recoveryStart: string; 12 | icon: string; 13 | support: string; 14 | } 15 | 16 | export type IdentityProviderWithMetadata = IdentityProvider & { 17 | metadata: IdentityProviderMetaData; 18 | }; 19 | 20 | export interface AccountWorkerInput { 21 | credentialInput: CredentialInputNoSeed; 22 | expiry: TransactionExpiry.Type; 23 | } 24 | 25 | /** 26 | * The list of possible statuses returned by an identity provider 27 | * when querying for an identity object. 28 | */ 29 | export enum IdentityProviderIdentityStatus { 30 | /** Pending identity verification and initial account creation. */ 31 | Pending = 'pending', 32 | /** The identity creation failed or was rejected. */ 33 | Error = 'error', 34 | /** The identity is ready and the initial account was created and is on chain. */ 35 | Done = 'done', 36 | } 37 | export interface PendingIdentityTokenContainer { 38 | status: IdentityProviderIdentityStatus.Pending; 39 | detail: string; 40 | } 41 | export interface DoneIdentityTokenContainer { 42 | status: IdentityProviderIdentityStatus.Done; 43 | token: { identityObject: Versioned }; 44 | detail: string; 45 | } 46 | export interface ErrorIdentityTokenContainer { 47 | status: IdentityProviderIdentityStatus.Error; 48 | detail: string; 49 | } 50 | export type IdentityTokenContainer = 51 | | PendingIdentityTokenContainer 52 | | DoneIdentityTokenContainer 53 | | ErrorIdentityTokenContainer; 54 | -------------------------------------------------------------------------------- /examples/wallet/tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["./**/*.ts", "./**/*.tsx"] 3 | } 4 | -------------------------------------------------------------------------------- /examples/wallet/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "ts-node/node16/tsconfig.json", 3 | "ts-node": { 4 | "files": true, 5 | "esm": true 6 | }, 7 | "compilerOptions": { 8 | "noEmit": true, 9 | "types": ["vite-plugin-svgr/client"], 10 | "target": "ES2020", 11 | "lib": ["dom", "dom.iterable", "esnext"], 12 | "baseUrl": ".", 13 | "allowJs": true, 14 | "skipLibCheck": true, 15 | "esModuleInterop": true, 16 | "allowSyntheticDefaultImports": true, 17 | "strict": true, 18 | "noFallthroughCasesInSwitch": true, 19 | "module": "esnext", 20 | "moduleResolution": "bundler", 21 | "resolveJsonModule": true, 22 | "isolatedModules": true, 23 | "downlevelIteration": true, 24 | "jsx": "react" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/wallet/vite.config.ts: -------------------------------------------------------------------------------- 1 | import react from '@vitejs/plugin-react-swc'; 2 | import { defineConfig } from 'vite'; 3 | import svgr from 'vite-plugin-svgr'; 4 | import topLevelAwait from 'vite-plugin-top-level-await'; 5 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 6 | // @ts-ignore 7 | import wasm from 'vite-plugin-wasm'; 8 | 9 | export default defineConfig({ 10 | plugins: [ 11 | react(), 12 | svgr(), 13 | wasm(), 14 | topLevelAwait(), // For legacy browser compatibility 15 | ], 16 | resolve: { 17 | alias: { 18 | '@concordium/rust-bindings': '@concordium/rust-bindings/bundler', // Resolve bundler-specific wasm entrypoints. 19 | }, 20 | }, 21 | worker: { 22 | plugins: [wasm(), topLevelAwait()], 23 | }, 24 | }); 25 | -------------------------------------------------------------------------------- /packages/ccd-js-gen/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog - ccd-js-gen 2 | 3 | ## 1.2.1 4 | 5 | ### Changed 6 | 7 | - Update peer depedency for `@concordium/web-sdk` to support any version above `7` 8 | 9 | ## 1.2.0 10 | 11 | - Fix issue related to inferring module type names from the input file name, by removing characters, which are not valid in type names. 12 | - Improve information when reporting progress during code-generation. 13 | - Generate `createParameterWebWallet` and `createParameterWebWallet` functions for constructing the smart contract parameters in the format used by the Concordium Web-Wallet. 14 | - Minor breaking change: `createParameter` function for contract entries and `createParameter` function in module are no longer generated when parameter schema type is `Unit`. These functions are mainly used internally, but are still exposed. 15 | - Fix bug for generating JSON for schema type `ULeb128` and `ILeb128`. 16 | - Add optional flag `--ts-nocheck`, enabling it will add `// @ts-nocheck` in each generated file. 17 | - Add `--output-type ` flag to CLI allowing to specify whether to generate TypeScript or JavaScript directly. 18 | - Fix the executable version of the package on Windows. 19 | 20 | ## 1.0.1 21 | 22 | - Fix missing `bin` in deployed package. 23 | 24 | ## 1.0.0 25 | 26 | - Initial release 27 | -------------------------------------------------------------------------------- /packages/ccd-js-gen/bin/ccd-js-gen.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * This file executes the `main` function in the `cli` file of the project. 5 | * 6 | * The execution immediately spawns a child process with node to get around some platform-specific issues. 7 | * See https://github.com/Concordium/concordium-node-sdk-js/pull/315 for more details. 8 | * */ 9 | 10 | import { spawn } from 'node:child_process'; 11 | import * as path from 'path'; 12 | import { fileURLToPath, pathToFileURL } from 'node:url'; 13 | 14 | // Find the path to this script and resolve any symlinks. 15 | // Then use it to locate and execute the `cli.js` file while forwarding all arguments. 16 | const scriptPath = fileURLToPath(import.meta.url); 17 | const binFolder = path.parse(scriptPath).dir; 18 | const cliPath = pathToFileURL(path.join(binFolder, '..', 'lib', 'src', 'cli.js')); 19 | const node = spawn('node', [ 20 | '--no-warnings', 21 | '-e', 22 | `import('${cliPath}').then(cli => cli.main())`, 23 | '--', 24 | ...process.argv, 25 | ]); 26 | 27 | // Forward stdout from child process. 28 | node.stdout.on('data', (data) => { 29 | console.log(`${data}`); 30 | }); 31 | 32 | // Forward stderr from child process. 33 | node.stderr.on('data', (data) => { 34 | console.error(`${data}`); 35 | }); 36 | 37 | // Forward exit codes from child process. 38 | node.on('close', (code) => { 39 | process.exit(code); 40 | }); 41 | -------------------------------------------------------------------------------- /packages/ccd-js-gen/jest.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from 'jest'; 2 | import type {} from 'ts-jest'; 3 | 4 | export const esModules = ['@noble/ed25519', '@concordium/web-sdk']; 5 | 6 | const config: Config = { 7 | preset: 'ts-jest/presets/js-with-ts-esm', 8 | moduleNameMapper: { 9 | '^(\\.\\.?\\/.+)\\.js$': '$1', // Remap esmodule file extensions 10 | }, 11 | transformIgnorePatterns: [`node_modules/(?!${esModules.join('|')})`], 12 | }; 13 | 14 | export default config; 15 | -------------------------------------------------------------------------------- /packages/ccd-js-gen/test/resources/test-bench.wasm.v1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/packages/ccd-js-gen/test/resources/test-bench.wasm.v1 -------------------------------------------------------------------------------- /packages/ccd-js-gen/test/resources/wCCD.wasm.v1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/packages/ccd-js-gen/test/resources/wCCD.wasm.v1 -------------------------------------------------------------------------------- /packages/ccd-js-gen/test/testHelpers.ts: -------------------------------------------------------------------------------- 1 | import * as ts from 'typescript'; 2 | 3 | /** 4 | * Use typescript compiler to typecheck the provided files, fails the test otherwise. 5 | * @param {string[]} files Typescript files to type check. 6 | */ 7 | export function assertTypeChecks(files: string[]) { 8 | const program = ts.createProgram(files, { 9 | noEmit: true, 10 | target: ts.ScriptTarget.ES2022, 11 | moduleResolution: ts.ModuleResolutionKind.NodeNext, 12 | module: ts.ModuleKind.NodeNext, 13 | }); 14 | const emitResult = program.emit(); 15 | 16 | const allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics); 17 | 18 | const errors = allDiagnostics.map((diagnostic) => { 19 | if (diagnostic.file) { 20 | const { line, character } = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start!); 21 | const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); 22 | return `${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`; 23 | } else { 24 | return ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); 25 | } 26 | }); 27 | expect(errors).toEqual([]); 28 | expect(emitResult.emitSkipped).toBeFalsy(); 29 | } 30 | -------------------------------------------------------------------------------- /packages/ccd-js-gen/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["src/**/*", "package.json"] // package.json is used by the CLI, therefore it is included here. 4 | } 5 | -------------------------------------------------------------------------------- /packages/ccd-js-gen/tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["./src/**/*", "bin/**/*"] 4 | } 5 | -------------------------------------------------------------------------------- /packages/ccd-js-gen/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-base.json", 3 | "include": ["src/**/*", "test/**/*", "package.json", "jest.config.ts"], 4 | "compilerOptions": { 5 | "module": "NodeNext", 6 | "moduleResolution": "NodeNext", 7 | "outDir": "./lib", 8 | "lib": ["ES2021", "dom"], // "dom" is only added to get the typings for the global variable `WebAssembly`. 9 | "resolveJsonModule": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/react-components/.gitignore: -------------------------------------------------------------------------------- 1 | /dist/ 2 | /node_modules/ 3 | -------------------------------------------------------------------------------- /packages/react-components/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@concordium/react-components", 3 | "version": "0.6.1", 4 | "description": "Utility library of React components for building dApps that interact with the Concordium blockchain.", 5 | "author": "Concordium Software", 6 | "license": "Apache-2.0", 7 | "browser": "./dist/index.js", 8 | "types": "./dist/index.d.ts", 9 | "exports": { 10 | ".": { 11 | "types": "./dist/index.d.ts", 12 | "default": "./dist/index.js" 13 | } 14 | }, 15 | "files": [ 16 | "./dist", 17 | "./src" 18 | ], 19 | "repository": { 20 | "type": "git", 21 | "url": "https://github.com/Concordium/concordium-node-sdk-js/tree/main/packages/react-components" 22 | }, 23 | "scripts": { 24 | "lint": "eslint . --cache --ext ts,tsx --report-unused-disable-directives --max-warnings 0", 25 | "lint-fix": "yarn lint --fix", 26 | "prettier": "prettier . --ignore-path ../../.gitignore --ignore-path ../../.prettierignore --ignore-path .gitignore", 27 | "fmt": "yarn prettier --write", 28 | "fmt-check": "yarn prettier --check", 29 | "build": "tsc" 30 | }, 31 | "dependencies": { 32 | "@concordium/wallet-connectors": "workspace:^", 33 | "@protobuf-ts/grpcweb-transport": "^2.9.4", 34 | "buffer": "^6.0.3" 35 | }, 36 | "devDependencies": { 37 | "@tsconfig/recommended": "^1.0.1", 38 | "@types/node": "^18.11.17", 39 | "@types/react": "^18", 40 | "eslint": "8", 41 | "prettier": "^3.2.5", 42 | "typescript": "^5.2.2" 43 | }, 44 | "peerDependencies": { 45 | "@concordium/web-sdk": ">= 7", 46 | "react": "^18" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /packages/react-components/src/error.ts: -------------------------------------------------------------------------------- 1 | export function errorString(err: any): string { 2 | return (err as Error).message || (err as string); 3 | } 4 | -------------------------------------------------------------------------------- /packages/react-components/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useConnect'; 2 | export * from './useConnection'; 3 | export * from './useContractSelector'; 4 | export * from './useGrpcClient'; 5 | export * from './useModuleSchemaRpc'; 6 | export * from './useWalletConnectorSelector'; 7 | export * from './WithWalletConnector'; 8 | export * from '@concordium/wallet-connectors'; 9 | -------------------------------------------------------------------------------- /packages/react-components/src/useGrpcClient.ts: -------------------------------------------------------------------------------- 1 | import { Network } from '@concordium/wallet-connectors'; 2 | import { ConcordiumGRPCClient } from '@concordium/web-sdk'; 3 | import { GrpcWebFetchTransport } from '@protobuf-ts/grpcweb-transport'; 4 | import { useEffect, useState } from 'react'; 5 | 6 | /** 7 | * React hook that obtains a gRPC Web client for interacting with a node on the appropriate network. 8 | */ 9 | export function useGrpcClient({ grpcOpts }: Network): ConcordiumGRPCClient | undefined { 10 | const [client, setClient] = useState(); 11 | useEffect(() => { 12 | if (!grpcOpts) { 13 | return setClient(undefined); 14 | } 15 | // No exceptions should ever be thrown from here. 16 | setClient(new ConcordiumGRPCClient(new GrpcWebFetchTransport(grpcOpts))); 17 | }, [grpcOpts]); 18 | return client; 19 | } 20 | -------------------------------------------------------------------------------- /packages/react-components/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/recommended/tsconfig.json", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "declarationMap": true, 6 | "module": "ES2020", 7 | "moduleResolution": "bundler", 8 | "sourceMap": true, 9 | "outDir": "./dist" 10 | }, 11 | "include": ["./src"] 12 | } 13 | -------------------------------------------------------------------------------- /packages/rust-bindings/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = ["packages/*"] 3 | resolver = "2" 4 | 5 | [workspace.package] 6 | authors = ["Concordium AG "] 7 | edition = "2021" 8 | 9 | [profile.dev] 10 | opt-level = 3 11 | 12 | [workspace.dependencies] 13 | anyhow = "1.0" 14 | concordium_rust_bindings_common = { path = "./packages/common" } 15 | either = "1.6" 16 | hex = "0.4" 17 | rand = { version = "0.8" } 18 | getrandom = { version = "0.2", features = ["js"] } 19 | serde = { version = "1.0", features = ["derive"] } 20 | serde_json = "1.0" 21 | serde-wasm-bindgen = "0.5" 22 | thiserror = "1.0" 23 | wasm-bindgen = { version = "0.2", features = ["serde-serialize"] } 24 | 25 | [workspace.dependencies.concordium_base] 26 | path = "../../deps/concordium-base/rust-src/concordium_base" 27 | 28 | [workspace.dependencies.ed25519_hd_key_derivation] 29 | path = "../../deps/concordium-base/rust-src/ed25519_hd_key_derivation" 30 | 31 | [workspace.dependencies.key_derivation] 32 | path = "../../deps/concordium-base/rust-src/key_derivation" 33 | 34 | [workspace.dependencies.wallet_library] 35 | path = "../../deps/concordium-base/rust-src/wallet_library" 36 | -------------------------------------------------------------------------------- /packages/rust-bindings/README.md: -------------------------------------------------------------------------------- 1 | # Concordium Rust bindings 2 | 3 | [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.0-4baaaa.svg)](https://github.com/Concordium/.github/blob/main/.github/CODE_OF_CONDUCT.md) 4 | 5 | Bindings for the Rust functions that are used by the SDK. 6 | 7 | Please see the 8 | [documentation](https://developer.concordium.software/concordium-node-sdk-js/index.html) 9 | for more information 10 | -------------------------------------------------------------------------------- /packages/rust-bindings/packages/common/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "concordium_rust_bindings_common" 3 | authors.workspace = true 4 | version = "0.1.0" 5 | edition.workspace = true 6 | 7 | [dependencies] 8 | wasm-bindgen.workspace = true 9 | 10 | [lib] 11 | name = "concordium_rust_bindings_common" 12 | # crate-type = ["lib"] 13 | path = "src/lib.rs" 14 | -------------------------------------------------------------------------------- /packages/rust-bindings/packages/common/src/helpers.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::Display; 2 | use wasm_bindgen::prelude::*; 3 | 4 | use crate::types::JsonString; 5 | 6 | pub type JsResult = Result; 7 | 8 | pub fn to_js_error(error: impl Display) -> JsError { JsError::new(&format!("{}", error)) } 9 | -------------------------------------------------------------------------------- /packages/rust-bindings/packages/common/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod helpers; 2 | pub mod types; 3 | -------------------------------------------------------------------------------- /packages/rust-bindings/packages/common/src/types.rs: -------------------------------------------------------------------------------- 1 | pub type JsonString = String; 2 | pub type HexString = String; 3 | pub type Base58String = String; 4 | -------------------------------------------------------------------------------- /packages/rust-bindings/packages/dapp/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "concordium_rust_bindings_dapp" 3 | authors.workspace = true 4 | version = "0.1.0" 5 | edition.workspace = true 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | serde_json.workspace = true 11 | wasm-bindgen.workspace = true 12 | anyhow.workspace = true 13 | hex.workspace = true 14 | serde-wasm-bindgen.workspace = true 15 | getrandom.workspace = true 16 | concordium_base.workspace = true 17 | concordium_rust_bindings_common.workspace = true 18 | 19 | [lib] 20 | name = "concordium_rust_bindings_dapp" 21 | crate-type = ["cdylib"] 22 | path = "src/lib.rs" 23 | -------------------------------------------------------------------------------- /packages/rust-bindings/packages/dapp/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod aux_functions; 2 | pub mod external_functions; 3 | -------------------------------------------------------------------------------- /packages/rust-bindings/packages/wallet/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "concordium_rust_bindings_wallet" 3 | authors.workspace = true 4 | version = "0.1.0" 5 | edition.workspace = true 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | serde.workspace = true 11 | serde_json.workspace = true 12 | wasm-bindgen.workspace = true 13 | anyhow.workspace = true 14 | hex.workspace = true 15 | either.workspace = true 16 | thiserror.workspace = true 17 | rand.workspace = true 18 | getrandom.workspace = true 19 | serde-wasm-bindgen.workspace = true 20 | concordium_base.workspace = true 21 | ed25519_hd_key_derivation.workspace = true 22 | key_derivation.workspace = true 23 | wallet_library.workspace = true 24 | concordium_rust_bindings_common.workspace = true 25 | chrono = "0.4.35" # patch version needs to to be locked for compatibility reasons 26 | serde_with = "3.0" 27 | 28 | [lib] 29 | name = "concordium_rust_bindings_wallet" 30 | crate-type = ["cdylib"] 31 | path = "src/lib.rs" 32 | -------------------------------------------------------------------------------- /packages/rust-bindings/packages/wallet/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod aux_functions; 2 | pub mod external_functions; 3 | 4 | #[macro_use] 5 | extern crate serde_json; 6 | extern crate hex; 7 | -------------------------------------------------------------------------------- /packages/rust-bindings/scripts/build-react-native-dapp.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | 3 | import { convertWasmToJs, copyToFolder } from './build-scripts'; 4 | 5 | const dappBundlerPath = path.join(__dirname, '../lib/dapp/bundler'); 6 | const dappOutPath = path.join(__dirname, '../lib/dapp/react-native'); 7 | 8 | copyToFolder(dappBundlerPath, dappOutPath); 9 | convertWasmToJs(dappOutPath); 10 | -------------------------------------------------------------------------------- /packages/rust-bindings/scripts/build-react-native-wallet.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | 3 | import { convertWasmToJs, copyToFolder } from './build-scripts'; 4 | 5 | const walletBundlerPath = path.join(__dirname, '../lib/wallet/bundler'); 6 | const walletOutPath = path.join(__dirname, '../lib/wallet/react-native'); 7 | 8 | copyToFolder(walletBundlerPath, walletOutPath); 9 | convertWasmToJs(walletOutPath); 10 | -------------------------------------------------------------------------------- /packages/rust-bindings/scripts/build-scripts.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | 3 | /** 4 | * Builds package for react native by: 5 | * 1. Copying output from wasm-pack built with bundler target 6 | * 2. Converting wasm file to js with [wasm2js]{@link https://github.com/WebAssembly/binaryen/blob/main/src/wasm2js.h} 7 | * 3. Replacing references to wasm file with corresponding references to converted file. 8 | */ 9 | import copyfiles from 'copyfiles'; 10 | import { exec as _exec } from 'node:child_process'; 11 | import fs from 'node:fs'; 12 | import path from 'node:path'; 13 | import util from 'node:util'; 14 | 15 | const exec = util.promisify(_exec); 16 | 17 | const WASM_FILENAME = 'index_bg.wasm'; 18 | const WASM_FILENAME_JS = `${WASM_FILENAME}.js`; 19 | 20 | // Copy files to react native folder 21 | export const copyToFolder = (bundlerPath: string, outPath: string) => 22 | copyfiles( 23 | [`${bundlerPath}/index*`, `${bundlerPath}/package.json`, outPath], 24 | { up: bundlerPath.split('/').length, flat: true }, 25 | () => {} // no-op 26 | ); 27 | 28 | export const convertWasmToJs = async (outPath: string) => { 29 | // Convert files using `wasm2js` 30 | await exec(`wasm2js ${path.join(outPath, WASM_FILENAME)} -o ${path.join(outPath, WASM_FILENAME_JS)}`); 31 | 32 | // Remove unused wasm file 33 | fs.rmSync(path.join(outPath, WASM_FILENAME)); 34 | 35 | // Replace references to wasm file with references to converted file 36 | ['index.js', 'index_bg.js'] 37 | .map((filename) => path.join(outPath, filename)) 38 | .forEach((file) => { 39 | let content = fs.readFileSync(file, 'utf-8'); 40 | content = content.replace(WASM_FILENAME, WASM_FILENAME_JS); 41 | fs.writeFileSync(file, content, 'utf-8'); 42 | }); 43 | }; 44 | -------------------------------------------------------------------------------- /packages/rust-bindings/ts-src/dapp.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | import { Buffer } from 'buffer/index.js'; 3 | 4 | import { initSync } from '../lib/dapp/web/esm'; 5 | import wasmBase64 from '../lib/dapp/web/esm/index_bg.wasm'; 6 | 7 | // Expected to resolve to base64 encoded bytes of wasm module 8 | 9 | const bytes = Buffer.from(wasmBase64 as unknown as string, 'base64'); 10 | initSync(bytes); 11 | 12 | export * from '../lib/dapp/web/esm'; 13 | -------------------------------------------------------------------------------- /packages/rust-bindings/ts-src/wallet.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | import { Buffer } from 'buffer/index.js'; 3 | 4 | import { initSync } from '../lib/wallet/web/esm'; 5 | import wasmBase64 from '../lib/wallet/web/esm/index_bg.wasm'; 6 | 7 | // Expected to resolve to base64 encoded bytes of wasm module 8 | 9 | const bytes = Buffer.from(wasmBase64 as unknown as string, 'base64'); 10 | initSync(bytes); 11 | 12 | export * from '../lib/wallet/web/esm'; 13 | -------------------------------------------------------------------------------- /packages/rust-bindings/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["./ts-src/**/*"], 4 | "compilerOptions": { 5 | "rootDir": "./ts-src", 6 | "declaration": false, 7 | "outDir": "./lib/web" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/rust-bindings/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-base.json", 3 | "include": ["./ts-src/**/*", "./scripts/**/*", "./build/**/*", "./webpack.config.ts"], 4 | "compilerOptions": { 5 | "composite": false, 6 | "lib": ["ES2020", "dom"] 7 | }, 8 | "ts-node": { 9 | "compilerOptions": { 10 | "module": "CommonJS" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/sdk/.size-limit.ts: -------------------------------------------------------------------------------- 1 | import type { SizeLimitConfig } from 'size-limit'; 2 | 3 | module.exports = [ 4 | { 5 | name: 'GRPC web client tree shaking', 6 | path: 'lib/esm/index.js', 7 | limit: '54 KB', 8 | import: '{ ConcordiumGRPCWebClient }', 9 | }, 10 | ] satisfies SizeLimitConfig; 11 | -------------------------------------------------------------------------------- /packages/sdk/babel.config.cjs: -------------------------------------------------------------------------------- 1 | /** 2 | * Used for react-native tests configured in `jest.config.react-native.ts` 3 | */ 4 | 5 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 6 | module.exports = { 7 | presets: ['module:metro-react-native-babel-preset'], 8 | }; 9 | -------------------------------------------------------------------------------- /packages/sdk/jest.config.react-native.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from 'jest'; 2 | 3 | import nodeConfig, { esModules } from './jest.config.ts'; 4 | 5 | const rnEsModules = [...esModules, 'react-native', '@react-native']; 6 | 7 | const config: Config = { 8 | preset: 'react-native', 9 | moduleNameMapper: { 10 | ...nodeConfig.moduleNameMapper, 11 | // No idea why, but the following declaration seems to force the resolver to not respect package.json exports. 12 | // This hack is needed due to importing from `/src/index.js` instead of deep importing from the file where it's declared. 13 | '@concordium/rust-bindings/wallet': '@concordium/rust-bindings/wallet', 14 | }, 15 | globals: { 16 | __ENV__: 'react-native', 17 | }, 18 | transformIgnorePatterns: [`node_modules/(?!${rnEsModules.join('|')})`], 19 | transform: { 20 | '^.+\\.jsx$': 'babel-jest', 21 | '^.+\\.tsx?$': 'ts-jest', 22 | }, 23 | }; 24 | 25 | export default config; 26 | -------------------------------------------------------------------------------- /packages/sdk/jest.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from 'jest'; 2 | 3 | export const esModules = ['@noble/ed25519']; 4 | 5 | const config: Config = { 6 | preset: 'ts-jest/presets/js-with-ts-esm', 7 | moduleNameMapper: { 8 | '^(\\.\\.?\\/.+)\\.js$': '$1', // Remap esmodule file extensions 9 | }, 10 | globals: { 11 | __ENV__: 'node', 12 | }, 13 | transformIgnorePatterns: [`node_modules/(?!${esModules.join('|')})`], 14 | // Needed due to a bug in Jest, issue: https://github.com/jestjs/jest/issues/11617 15 | workerThreads: true, 16 | }; 17 | 18 | export default config; 19 | -------------------------------------------------------------------------------- /packages/sdk/jest.config.web.ts: -------------------------------------------------------------------------------- 1 | import { Config } from 'jest'; 2 | 3 | import baseConfig from './jest.config.ts'; 4 | 5 | const config: Config = { 6 | ...baseConfig, 7 | testEnvironment: 'jsdom', 8 | globals: { 9 | __ENV__: 'web', 10 | }, 11 | setupFiles: ['/test/setup.web.ts'], 12 | }; 13 | 14 | export default config; 15 | -------------------------------------------------------------------------------- /packages/sdk/scripts/proto-node-esm-compat.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | import fs from 'fs'; 3 | import { glob } from 'glob'; 4 | 5 | const protoRoot = process.argv[2]; // First 2 arguments are node and path to this script. 3rd is expected to be location of generated proto type files. 6 | 7 | if (!protoRoot) { 8 | throw new Error('Please supply a dir for the proto types to convert'); 9 | } 10 | 11 | const files = await glob(protoRoot + '/**/*.ts'); 12 | files.forEach((file) => { 13 | let content = fs.readFileSync(file, 'utf-8'); 14 | 15 | content = content 16 | .split('\n') 17 | .map((s) => s.replace(/^(import .+? from ["']\..+?)(["'];)$/, '$1.js$2')) 18 | .join('\n'); 19 | 20 | fs.writeFileSync(file, content, 'utf-8'); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/sdk/src/accountHelpers.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AccountInfo, 3 | AccountInfoBaker, 4 | AccountInfoDelegator, 5 | AccountInfoType, 6 | ReduceStakePendingChange, 7 | RemovalPendingChange, 8 | StakePendingChange, 9 | StakePendingChangeType, 10 | } from './types.js'; 11 | 12 | /** 13 | * Whether {@link AccountInfo} parameter given is of type {@link AccountInfoDelegator}, i.e. the account is a delegator 14 | * 15 | * @deprecated check `type` member instead. 16 | */ 17 | export const isDelegatorAccount = (ai: AccountInfo): ai is AccountInfoDelegator => 18 | ai.type === AccountInfoType.Delegator; 19 | 20 | /** 21 | * Whether {@link AccountInfo} parameter given is of type {@link AccountInfoBaker}, i.e. the account is a baker. 22 | * 23 | * @deprecated check `type` member instead. 24 | */ 25 | export const isBakerAccount = (ai: AccountInfo): ai is AccountInfoBaker => ai.type === AccountInfoType.Baker; 26 | 27 | /** 28 | * Whether the pending change given is of type {@link ReduceStakePendingChange} 29 | * 30 | * @deprecated check `change` member instead. 31 | */ 32 | export const isReduceStakePendingChange = (spc: StakePendingChange): spc is ReduceStakePendingChange => 33 | spc.change === StakePendingChangeType.ReduceStake; 34 | 35 | /** 36 | * Whether the pending change given is of type {@link RemovalPendingChange} 37 | * 38 | * @deprecated check `change` member instead. 39 | */ 40 | export const isRemovalPendingChange = (spc: StakePendingChange): spc is RemovalPendingChange => 41 | spc.change === StakePendingChangeType.RemoveStake; 42 | -------------------------------------------------------------------------------- /packages/sdk/src/cis2/index.ts: -------------------------------------------------------------------------------- 1 | export type { CIS2 } from './util.js'; 2 | export { 3 | tokenAddressFromBase58, 4 | tokenAddressToBase58, 5 | deserializeCIS2Event, 6 | deserializeCIS2EventsFromInvokationResult, 7 | deserializeCIS2EventsFromSummary, 8 | parseCIS2RejectionError, 9 | } from './util.js'; 10 | export * from './CIS2Contract.js'; 11 | -------------------------------------------------------------------------------- /packages/sdk/src/cis3/index.ts: -------------------------------------------------------------------------------- 1 | export { CIS3 } from './util.js'; 2 | export * from './CIS3Contract.js'; 3 | -------------------------------------------------------------------------------- /packages/sdk/src/cis4/index.ts: -------------------------------------------------------------------------------- 1 | export { CIS4, Web3IdSigner } from './util.js'; 2 | export * from './CIS4Contract.js'; 3 | -------------------------------------------------------------------------------- /packages/sdk/src/constants.ts: -------------------------------------------------------------------------------- 1 | import * as Energy from './types/Energy.js'; 2 | 3 | export const DEFAULT_INVOKE_ENERGY: Energy.Type = Energy.create(1000000n); 4 | -------------------------------------------------------------------------------- /packages/sdk/src/grpc/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | ConcordiumGRPCClient, 3 | ConcordiumGRPCWebClient, 4 | getAccountIdentifierInput, 5 | getBlockHashInput, 6 | } from './GRPCClient.js'; 7 | -------------------------------------------------------------------------------- /packages/sdk/src/hash.ts: -------------------------------------------------------------------------------- 1 | import { Buffer } from 'buffer/index.js'; 2 | import hash from 'hash.js'; 3 | 4 | export function sha256(data: (Buffer | Uint8Array)[]): Buffer { 5 | const sha256Hash = hash.sha256(); 6 | data.forEach((input) => sha256Hash.update(input)); 7 | return Buffer.from(sha256Hash.digest('hex'), 'hex'); 8 | } 9 | -------------------------------------------------------------------------------- /packages/sdk/src/id/idProofTypes.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | AtomicProof, 3 | GenericAtomicStatement, 4 | GenericMembershipStatement, 5 | GenericNonMembershipStatement, 6 | GenericRangeStatement, 7 | GenericRevealStatement, 8 | } from '../commonProofTypes.js'; 9 | import type { AttributeKey, CryptographicParameters, IdentityObjectV1, Network, Versioned } from '../types.js'; 10 | 11 | export type RangeStatement = GenericRangeStatement; 12 | export type NonMembershipStatement = GenericNonMembershipStatement; 13 | export type MembershipStatement = GenericMembershipStatement; 14 | export type RevealStatement = GenericRevealStatement; 15 | 16 | export type AtomicStatement = GenericAtomicStatement; 17 | export type IdStatement = AtomicStatement[]; 18 | 19 | export type IdProofInput = { 20 | idObject: IdentityObjectV1; 21 | globalContext: CryptographicParameters; 22 | seedAsHex: string; 23 | net: Network; 24 | identityProviderIndex: number; 25 | identityIndex: number; 26 | credNumber: number; 27 | statement: IdStatement; 28 | challenge: string; // Hex 29 | }; 30 | 31 | export type IdProof = { 32 | proofs: AtomicProof[]; 33 | }; 34 | 35 | export type IdProofOutput = { 36 | credential: string; 37 | proof: Versioned; 38 | }; 39 | 40 | /** 41 | * The attributes that can be used for range statements 42 | */ 43 | export const attributesWithRange: AttributeKey[] = ['dob', 'idDocIssuedAt', 'idDocExpiresAt']; 44 | 45 | /** 46 | * The attributes that can be used for (non)membership statements 47 | */ 48 | export const attributesWithSet: AttributeKey[] = [ 49 | 'countryOfResidence', 50 | 'nationality', 51 | 'idDocType', 52 | 'idDocIssuer', 53 | 'legalCountry', 54 | ]; 55 | -------------------------------------------------------------------------------- /packages/sdk/src/id/index.ts: -------------------------------------------------------------------------------- 1 | export * from './idProofs.js'; 2 | export * from './idProofTypes.js'; 3 | -------------------------------------------------------------------------------- /packages/sdk/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './pub/types.js'; 2 | export * from './pub/util.js'; 3 | export * from './pub/wasm.js'; 4 | export * from './pub/id.js'; 5 | export * from './pub/grpc.js'; 6 | export * from './pub/cis0.js'; 7 | export * from './pub/cis2.js'; 8 | export * from './pub/cis3.js'; 9 | export * from './pub/cis4.js'; 10 | export * from './pub/schema.js'; 11 | export * from './pub/web3-id.js'; 12 | -------------------------------------------------------------------------------- /packages/sdk/src/nodejs/grpc.ts: -------------------------------------------------------------------------------- 1 | import { ChannelCredentials } from '@grpc/grpc-js'; 2 | import { GrpcOptions, GrpcTransport } from '@protobuf-ts/grpc-transport'; 3 | 4 | import { ConcordiumGRPCClient } from '../grpc/GRPCClient.js'; 5 | 6 | /** 7 | * A concordium-node specific gRPC client wrapper. 8 | * This will not work in a browser environment, in which case {@link ConcordiumGRPCWebClient} 9 | * should be used instead. 10 | * 11 | * @example 12 | * import { ConcordiumGRPCNodeClient } from "..." 13 | * import { credentials } from '@grpc/grpc-js'; 14 | * 15 | * const creds = ...; // e.g. credentials.createInsecure(); 16 | * const client = new ConcordiumGRPCClient('127.0.0.1', 20000, creds); 17 | */ 18 | export class ConcordiumGRPCNodeClient extends ConcordiumGRPCClient { 19 | constructor(address: string, port: number, credentials: ChannelCredentials, options?: Partial) { 20 | const transport = new GrpcTransport({ 21 | host: `${address}:${port}`, 22 | channelCredentials: credentials, 23 | ...options, 24 | }); 25 | super(transport); 26 | } 27 | } 28 | 29 | export { credentials, ChannelCredentials, CallCredentials } from '@grpc/grpc-js'; 30 | -------------------------------------------------------------------------------- /packages/sdk/src/nodejs/index.ts: -------------------------------------------------------------------------------- 1 | export * from './grpc.js'; 2 | export * from './util.js'; 3 | export { decryptMobileWalletExport, EncryptedData } from './wallet/crypto.js'; 4 | export { MobileWalletExport } from './wallet/types.js'; 5 | -------------------------------------------------------------------------------- /packages/sdk/src/nodejs/util.ts: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs'; 2 | 3 | /** 4 | * Loads the module as a buffer, given the given filePath. 5 | * @param filePath the location of the module 6 | * @returns the module as a buffer 7 | */ 8 | export function getModuleBuffer(filePath: string): Buffer { 9 | return Buffer.from(fs.readFileSync(filePath)); 10 | } 11 | -------------------------------------------------------------------------------- /packages/sdk/src/nodejs/wallet/types.ts: -------------------------------------------------------------------------------- 1 | import { IdentityProvider, Versioned } from '../../types.js'; 2 | 3 | interface CredentialHolderInformation { 4 | idCredSecret: string; 5 | } 6 | 7 | interface AccountCredentialInformation { 8 | credentialHolderInformation: CredentialHolderInformation; 9 | prfKey: string; 10 | } 11 | 12 | interface PrivateIdObjectData { 13 | aci: AccountCredentialInformation; 14 | randomness: string; 15 | } 16 | 17 | export interface Identity { 18 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 19 | accounts: any[]; 20 | 21 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 22 | identityObject: any; 23 | identityProvider: IdentityProvider; 24 | 25 | name: string; 26 | nextAccountNumber: number; 27 | 28 | privateIdObjectData: PrivateIdObjectData; 29 | } 30 | 31 | interface Identities { 32 | identities: Identity[]; 33 | } 34 | 35 | export interface MobileWalletExport extends Versioned { 36 | type: 'concordium-mobile-wallet-data'; 37 | } 38 | -------------------------------------------------------------------------------- /packages/sdk/src/overwrites.d.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 2 | import { Buffer } from 'buffer/index.js'; 3 | 4 | declare module 'buffer/index.js' { 5 | export interface Buffer { 6 | readBigUInt64BE(offset: number): bigint; 7 | } 8 | } 9 | /* TODO: Find a way to have this typing without affecting dependencies using encodings 10 | declare module "stream" { 11 | export interface Readable { 12 | read(size?: number): globalThis.Buffer; 13 | } 14 | } 15 | */ 16 | -------------------------------------------------------------------------------- /packages/sdk/src/pub/cis0.ts: -------------------------------------------------------------------------------- 1 | // Functionality for working with the CIS0 standard 2 | export * from '../cis0.js'; 3 | -------------------------------------------------------------------------------- /packages/sdk/src/pub/cis2.ts: -------------------------------------------------------------------------------- 1 | // Functionality for working with the CIS2 standard 2 | export * from '../cis2/index.js'; 3 | -------------------------------------------------------------------------------- /packages/sdk/src/pub/cis3.ts: -------------------------------------------------------------------------------- 1 | // Functionality for working with the CIS3 standard 2 | export * from '../cis3/index.js'; 3 | -------------------------------------------------------------------------------- /packages/sdk/src/pub/cis4.ts: -------------------------------------------------------------------------------- 1 | // Functionality for working with the CIS4 standard 2 | export * from '../cis4/index.js'; 3 | -------------------------------------------------------------------------------- /packages/sdk/src/pub/grpc.ts: -------------------------------------------------------------------------------- 1 | // The GRPC client. 2 | export * from '../grpc/index.js'; 3 | -------------------------------------------------------------------------------- /packages/sdk/src/pub/id.ts: -------------------------------------------------------------------------------- 1 | // Functionality revolving around identities. 2 | export * from '../id/index.js'; 3 | -------------------------------------------------------------------------------- /packages/sdk/src/pub/nodejs.ts: -------------------------------------------------------------------------------- 1 | export * from '../nodejs/index.js'; 2 | -------------------------------------------------------------------------------- /packages/sdk/src/pub/schema.ts: -------------------------------------------------------------------------------- 1 | // Functionality for working with smart contract schemas. This uses the WASM at entrypoint `@concordium/rust-bindings/dapp`. 2 | export * from '../schema.js'; 3 | export * from '../schemaTypes.js'; 4 | -------------------------------------------------------------------------------- /packages/sdk/src/pub/util.ts: -------------------------------------------------------------------------------- 1 | export { toBuffer } from '../util.js'; 2 | -------------------------------------------------------------------------------- /packages/sdk/src/pub/wasm.ts: -------------------------------------------------------------------------------- 1 | // Functionality revolving around concordium domain types, which require the WASM at entrypoint `@concordium/rust-bindings/wallet`. 2 | export * from '../wasm/index.js'; 3 | -------------------------------------------------------------------------------- /packages/sdk/src/pub/web3-id.ts: -------------------------------------------------------------------------------- 1 | // Functionality revolving around Web3 ID credentials. 2 | export * from '../web3-id/index.js'; 3 | -------------------------------------------------------------------------------- /packages/sdk/src/ratioHelpers.ts: -------------------------------------------------------------------------------- 1 | import { Ratio } from './types.js'; 2 | 3 | /** 4 | * Collapses the Fraction into a single number. 5 | * If the denominator does not divide the numerator, the function rounds up; 6 | */ 7 | export function collapseRatio({ numerator, denominator }: Ratio): bigint { 8 | const quotient = numerator / denominator; 9 | if (numerator % denominator === 0n) { 10 | return quotient; 11 | } 12 | return 1n + quotient; 13 | } 14 | 15 | /** 16 | * Multiply a ratio with a bigint. 17 | * @param factor a number which should be multiplied with the ratio. If given a string, it will attempt to parse it to a bigint. 18 | * @returns the product as a ratio. 19 | */ 20 | export function multiplyRatio({ numerator, denominator }: Ratio, factor: bigint | string): Ratio { 21 | return { 22 | numerator: numerator * BigInt(factor), 23 | denominator, 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /packages/sdk/src/shims/ed25519/default.ts: -------------------------------------------------------------------------------- 1 | // We need sync methods for react native support. 2 | // https://www.npmjs.com/package/@noble/ed25519#usage 3 | export * from '@noble/ed25519'; 4 | -------------------------------------------------------------------------------- /packages/sdk/src/shims/ed25519/node.ts: -------------------------------------------------------------------------------- 1 | // To add support for node versions <19. 2 | // From https://www.npmjs.com/package/@noble/ed25519#usage 3 | import { webcrypto } from 'node:crypto'; 4 | 5 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 6 | // @ts-ignore 7 | if (!globalThis.crypto) globalThis.crypto = webcrypto; 8 | 9 | // eslint-disable-next-line import/export 10 | export * from '@noble/ed25519'; 11 | -------------------------------------------------------------------------------- /packages/sdk/src/shims/ed25519/react-native.ts: -------------------------------------------------------------------------------- 1 | // We need sync methods for react native support. 2 | // https://www.npmjs.com/package/@noble/ed25519#usage 3 | import * as ed from '@noble/ed25519'; 4 | import { sha512 } from '@noble/hashes/sha512'; 5 | 6 | ed.etc.sha512Async = (...m) => Promise.resolve(sha512(ed.etc.concatBytes(...m))); 7 | 8 | export * from '@noble/ed25519'; 9 | -------------------------------------------------------------------------------- /packages/sdk/src/types/NodeInfo.ts: -------------------------------------------------------------------------------- 1 | import type { BakerId, HexString } from '../types.js'; 2 | import type * as Duration from '../types/Duration.js'; 3 | import type * as Timestamp from '../types/Timestamp.js'; 4 | 5 | export interface NodeInfo { 6 | peerVersion: string; 7 | localTime: Timestamp.Type; 8 | peerUptime: Duration.Type; 9 | networkInfo: NodeNetworkInfo; 10 | details: NodeInfoDetails; 11 | } 12 | 13 | export interface NodeNetworkInfo { 14 | nodeId: HexString; 15 | peerTotalSent: bigint; 16 | peerTotalReceived: bigint; 17 | avgBpsIn: bigint; 18 | avgBpsOut: bigint; 19 | } 20 | 21 | export type NodeInfoDetails = NodeInfoDetails_Bootstrapper | NodeInfoDetails_Node; 22 | 23 | export interface NodeInfoDetails_Bootstrapper { 24 | tag: 'bootstrapper'; 25 | } 26 | 27 | export interface NodeInfoDetails_Node { 28 | tag: 'node'; 29 | consensusStatus: NodeInfoConsensusStatus; 30 | } 31 | 32 | export type NodeInfoConsensusStatus = NodeInfoConsensusStatusGeneric | NodeInfoConsensusStatusActive; 33 | 34 | export interface NodeInfoConsensusStatusGeneric { 35 | tag: 'notRunning' | 'passive'; 36 | } 37 | 38 | export interface NodeInfoConsensusStatusActive { 39 | tag: 'active'; 40 | bakerId: BakerId; 41 | status: BakerConsensusInfoStatus; 42 | } 43 | 44 | export type BakerConsensusInfoStatus = BakerConsensusInfoStatusGeneric | BakerConsensusInfoStatusPassiveCommitteeInfo; 45 | 46 | export interface BakerConsensusInfoStatusGeneric { 47 | tag: 'activeBakerCommitteeInfo' | 'activeFinalizerCommitteeInfo'; 48 | } 49 | 50 | export interface BakerConsensusInfoStatusPassiveCommitteeInfo { 51 | tag: 'passiveCommitteeInfo'; 52 | passiveCommitteeInfo: PassiveCommitteeInfo; 53 | } 54 | 55 | export enum PassiveCommitteeInfo { 56 | NotInCommittee = 0, 57 | AddedButNotActiveInCommittee = 1, 58 | AddedButWrongKeys = 2, 59 | } 60 | -------------------------------------------------------------------------------- /packages/sdk/src/types/PeerInfo.ts: -------------------------------------------------------------------------------- 1 | import type { HexString, IpAddressString } from '../types.js'; 2 | 3 | export interface PeerInfo { 4 | peerId: HexString; 5 | ip: IpAddressString; 6 | port: number; 7 | networkStats?: PeerNetworkStats; 8 | consensusInfo: PeerConsensusInfo; 9 | } 10 | 11 | export interface PeerNetworkStats { 12 | packetsSent: bigint; 13 | packetsReceived: bigint; 14 | latency: bigint; 15 | } 16 | 17 | export type PeerConsensusInfo = PeerConsensusInfoBootstrapper | PeerConsensusInfoCatchupStatus; 18 | 19 | export interface PeerConsensusInfoBootstrapper { 20 | tag: 'bootstrapper'; 21 | } 22 | 23 | export interface PeerConsensusInfoCatchupStatus { 24 | tag: 'nodeCatchupStatus'; 25 | catchupStatus: NodeCatchupStatus; 26 | } 27 | 28 | export enum NodeCatchupStatus { 29 | UpToDate = 0, 30 | Pending = 1, 31 | CatchingUp = 2, 32 | } 33 | -------------------------------------------------------------------------------- /packages/sdk/src/types/errors.ts: -------------------------------------------------------------------------------- 1 | import { RpcError } from '@protobuf-ts/runtime-rpc'; 2 | 3 | export { RpcError }; 4 | 5 | export function isRpcError(error: unknown): error is RpcError { 6 | return error instanceof RpcError; 7 | } 8 | -------------------------------------------------------------------------------- /packages/sdk/src/wasm/accountHelpers.ts: -------------------------------------------------------------------------------- 1 | import * as wasm from '@concordium/rust-bindings/wallet'; 2 | 3 | import { GenerateBakerKeysOutput } from '../types.js'; 4 | import * as AccountAddress from '../types/AccountAddress.js'; 5 | 6 | /** 7 | * Generates random baker keys for the specified account, that can be used with the configureBaker transaction 8 | * @param account the address of the account that the keys should be added to. 9 | * @returns an object containing the public baker keys, their associated proofs and their associated private keys. 10 | */ 11 | export function generateBakerKeys(account: AccountAddress.Type): GenerateBakerKeysOutput { 12 | const rawKeys = wasm.generateBakerKeys(AccountAddress.toBase58(account)); 13 | try { 14 | return JSON.parse(rawKeys); 15 | } catch (e) { 16 | throw new Error(rawKeys); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/sdk/src/wasm/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | getCredentialDeploymentTransactionHash, 3 | serializeCredentialDeploymentTransactionForSubmission, 4 | serializeCredentialDeploymentPayload, 5 | } from './serialization.js'; 6 | export { deserializeTransaction } from './deserialization.js'; 7 | export { generateBakerKeys } from './accountHelpers.js'; 8 | export * from './HdWallet.js'; 9 | export * from './identity.js'; 10 | export * from './credentialDeploymentTransactions.js'; 11 | export * from './web3Id.js'; 12 | -------------------------------------------------------------------------------- /packages/sdk/src/web3-id/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types.js'; 2 | export * from './proofs.js'; 3 | export * from './helpers.js'; 4 | export * from './grpc.js'; 5 | -------------------------------------------------------------------------------- /packages/sdk/test/ci/VerifiablePresentation.test.ts: -------------------------------------------------------------------------------- 1 | import { 2 | replaceDateWithTimeStampAttribute, 3 | reviveDateFromTimeStampAttribute, 4 | } from '../../src/types/VerifiablePresentation.js'; 5 | 6 | const dateValue = '2023-08-24T15:15:29.000Z'; 7 | const timestamp = 1692890129000; 8 | const withTimestamp = `{\"date\":{\"type\":\"date-time\",\"timestamp\":\"${dateValue}\"}}`; 9 | 10 | test('replaceDateWithTimeStampAttribute', () => { 11 | const withDate = { 12 | date: new Date(timestamp), 13 | }; 14 | const serialized = JSON.stringify(withDate, replaceDateWithTimeStampAttribute); 15 | expect(serialized).toBe(withTimestamp); 16 | }); 17 | 18 | test('reviveDateFromTimeStampAttribute', () => { 19 | const parsed = JSON.parse(withTimestamp, reviveDateFromTimeStampAttribute); 20 | expect(parsed.date).toStrictEqual(new Date(timestamp)); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/sdk/test/ci/accountHelpers.test.ts: -------------------------------------------------------------------------------- 1 | import { AccountAddress } from '../../src/index.js'; 2 | import { generateBakerKeys } from '../../src/wasm/accountHelpers.js'; 3 | 4 | test('generate baker keys', () => { 5 | const accountAddress = '3eP94feEdmhYiPC1333F9VoV31KGMswonuHk5tqmZrzf761zK5'; 6 | const keys = generateBakerKeys(AccountAddress.fromBase58(accountAddress)); 7 | expect(typeof keys.signatureVerifyKey).toBe('string'); 8 | expect(typeof keys.electionVerifyKey).toBe('string'); 9 | expect(typeof keys.aggregationVerifyKey).toBe('string'); 10 | expect(typeof keys.signatureSignKey).toBe('string'); 11 | expect(typeof keys.electionPrivateKey).toBe('string'); 12 | expect(typeof keys.aggregationSignKey).toBe('string'); 13 | expect(typeof keys.proofAggregation).toBe('string'); 14 | expect(typeof keys.proofSig).toBe('string'); 15 | expect(typeof keys.proofElection).toBe('string'); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/sdk/test/ci/resources/ars_infos.json: -------------------------------------------------------------------------------- 1 | { 2 | "v": 0, 3 | "value": { 4 | "1": { 5 | "arIdentity": 1, 6 | "arDescription": { 7 | "name": "AR-1", 8 | "url": "", 9 | "description": "" 10 | }, 11 | "arPublicKey": "b14cbfe44a02c6b1f78711176d5f437295367aa4f2a8c2551ee10d25a03adc69d61a332a058971919dad7312e1fc94c587a95c1e9f3070f1c739b9396b97ce8045b89ec10e0c33f75f803b1b2fb50edf8a45481eb037160d67590d1498aab88f" 12 | }, 13 | "2": { 14 | "arIdentity": 2, 15 | "arDescription": { 16 | "name": "AR-2", 17 | "url": "", 18 | "description": "" 19 | }, 20 | "arPublicKey": "b14cbfe44a02c6b1f78711176d5f437295367aa4f2a8c2551ee10d25a03adc69d61a332a058971919dad7312e1fc94c5a0f155cc4436ac5f14ad81e4717b2b250c3b780c4d8acd7b558682096960bc8fbfe94f9fe7398be5b247cdfc1fa2e961" 21 | }, 22 | "3": { 23 | "arIdentity": 3, 24 | "arDescription": { 25 | "name": "AR-3", 26 | "url": "", 27 | "description": "" 28 | }, 29 | "arPublicKey": "b14cbfe44a02c6b1f78711176d5f437295367aa4f2a8c2551ee10d25a03adc69d61a332a058971919dad7312e1fc94c5ab6f676acee16137608342e31f9190cc4449750386d4485db080314001c85215b01fdb4e911beb84a35ea8676ca284bf" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/sdk/test/ci/resources/auction-with-errors-schema.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/packages/sdk/test/ci/resources/auction-with-errors-schema.bin -------------------------------------------------------------------------------- /packages/sdk/test/ci/resources/cis1-wccd-schema-v0-versioned.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/packages/sdk/test/ci/resources/cis1-wccd-schema-v0-versioned.bin -------------------------------------------------------------------------------- /packages/sdk/test/ci/resources/cis2-nft-schema.bin: -------------------------------------------------------------------------------- 1 | CIS2-NFT balanceOftoken_idaddressAccount Contract mintownerAccount Contract tokens 2 | operatorOfownerAccount Contract addressAccount Contract  tokenMetadataurlhashNoneSome transfertoken_idamountfromAccount Contract toAccount Contract dataupdateOperatorupdateRemoveAddoperatorAccount Contract viewstateAccount Contract  owned_tokens operatorsAccount Contract 3 | all_tokens -------------------------------------------------------------------------------- /packages/sdk/test/ci/resources/cis2-wccd-schema-v1-versioned.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/packages/sdk/test/ci/resources/cis2-wccd-schema-v1-versioned.bin -------------------------------------------------------------------------------- /packages/sdk/test/ci/resources/expectedStatements.ts: -------------------------------------------------------------------------------- 1 | import { ContractAddress } from '../../../src/index.js'; 2 | import { CredentialStatement } from '../../../src/web3-id/types.ts'; 3 | 4 | export const expectedStatementMixed: CredentialStatement[] = [ 5 | { 6 | idQualifier: { 7 | type: 'sci', 8 | issuers: [ContractAddress.create(2101), ContractAddress.create(1337, 42)], 9 | }, 10 | statement: [ 11 | { 12 | attributeTag: 'b', 13 | lower: 80n, 14 | type: 'AttributeInRange', 15 | upper: 1237n, 16 | }, 17 | { 18 | attributeTag: 'c', 19 | set: ['aa', 'ff', 'zz'], 20 | type: 'AttributeInSet', 21 | }, 22 | ], 23 | }, 24 | { 25 | idQualifier: { 26 | type: 'sci', 27 | issuers: [ContractAddress.create(1338, 0)], 28 | }, 29 | statement: [ 30 | { 31 | attributeTag: 'a', 32 | lower: 80n, 33 | type: 'AttributeInRange', 34 | upper: 1237n, 35 | }, 36 | { 37 | attributeTag: 'd', 38 | set: ['aa', 'ff', 'zz'], 39 | type: 'AttributeNotInSet', 40 | }, 41 | ], 42 | }, 43 | { 44 | idQualifier: { 45 | type: 'cred', 46 | issuers: [0, 1, 2], 47 | }, 48 | statement: [ 49 | { 50 | attributeTag: 'firstName', 51 | type: 'RevealAttribute', 52 | }, 53 | ], 54 | }, 55 | ]; 56 | -------------------------------------------------------------------------------- /packages/sdk/test/ci/resources/icecream-schema.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/packages/sdk/test/ci/resources/icecream-schema.bin -------------------------------------------------------------------------------- /packages/sdk/test/ci/resources/icecream-with-schema.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/packages/sdk/test/ci/resources/icecream-with-schema.wasm -------------------------------------------------------------------------------- /packages/sdk/test/ci/resources/schema.ts: -------------------------------------------------------------------------------- 1 | export const V0_PIGGYBANK_SCHEMA = 'AQAAAAkAAABQaWdneUJhbmsBFQIAAAAGAAAASW50YWN0AgcAAABTbWFzaGVkAgAAAAAA'; 2 | export const CIS2_WCCD_STATE_SCHEMA = 3 | '//8CAQAAAA8AAABDSVMyLXdDQ0QtU3RhdGUAAQAAAAoAAABnZXRCYWxhbmNlAhQAAQAAAAUAAABvd25lchUCAAAABwAAAEFjY291bnQBAQAAAAsIAAAAQ29udHJhY3QBAQAAAAwbJQAAAA=='; 4 | export const CIS2_WCCD_STATE_GET_BALANCE_RETURN_VALUE_SCHEMA = 'GyUAAAA'; 5 | export const TEST_CONTRACT_SCHEMA = '//8CAQAAAAwAAABUZXN0Q29udHJhY3QBBAIDAQAAABAAAAByZWNlaXZlX2Z1bmN0aW9uBgYIBw=='; 6 | export const TEST_CONTRACT_RECEIVE_ERROR_SCHEMA = 'Bw'; 7 | export const TEST_CONTRACT_INIT_ERROR_SCHEMA = 'Aw'; 8 | export const AUCTION_WITH_ERRORS_VIEW_RETURN_VALUE_SCHEMA = 9 | 'FAAEAAAADQAAAGF1Y3Rpb25fc3RhdGUVAgAAAAoAAABOb3RTb2xkWWV0AgQAAABTb2xkAQEAAAALDgAAAGhpZ2hlc3RfYmlkZGVyFQIAAAAEAAAATm9uZQIEAAAAU29tZQEBAAAACwQAAABpdGVtFgIDAAAAZW5kDQ'; 10 | 11 | // contract: "test", init = (param = u64), receive = (name: "receive", param = u64, return = u64) 12 | export const TEST_CONTRACT_U64 = '//8DAQAAAAQAAAB0ZXN0AQAFAQAAAAcAAAByZWNlaXZlAgUFAA=='; 13 | -------------------------------------------------------------------------------- /packages/sdk/test/ci/resources/two-step-transfer-schema.bin: -------------------------------------------------------------------------------- 1 | two-step-transfer init_paramsaccount_holders transfer_agreement_thresholdtransfer_request_ttlrequeststransfer_amount 2 | target_account times_out_at 3 | supporters account_holders transfer_agreement_thresholdtransfer_request_ttlreceiveRequestTransfer 4 | SupportTransfer 5 | -------------------------------------------------------------------------------- /packages/sdk/test/ci/types.test.ts: -------------------------------------------------------------------------------- 1 | import { RpcError, isRpcError } from '../../src/index.js'; 2 | 3 | test('RPCError', () => { 4 | const rpcError: unknown = new RpcError('This is an RpcError'); 5 | const regError = new Error('This is a regular Error'); 6 | 7 | expect(isRpcError(rpcError)).toEqual(true); 8 | expect(isRpcError(regError)).toEqual(false); 9 | 10 | if (isRpcError(rpcError)) { 11 | expect(rpcError.code).toBeTruthy(); 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /packages/sdk/test/ci/types/AccountAddress.test.ts: -------------------------------------------------------------------------------- 1 | import { AccountAddress } from '../../../src/index.js'; 2 | 3 | test('Base58 decode-encode results is the same', () => { 4 | const address = AccountAddress.fromBuffer(new Uint8Array(32)); 5 | const base58 = AccountAddress.toBase58(address); 6 | const converted = AccountAddress.fromBase58(base58); 7 | expect(AccountAddress.equals(converted, address)).toBeTruthy(); 8 | }); 9 | 10 | test('Buffer encode-decode results is the same', () => { 11 | const address = AccountAddress.fromBase58('3VwCfvVskERFAJ3GeJy2mNFrzfChqUymSJJCvoLAP9rtAwMGYt'); 12 | const buffer = AccountAddress.toBuffer(address); 13 | const converted = AccountAddress.fromBuffer(buffer); 14 | expect(AccountAddress.equals(converted, address)).toBeTruthy(); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/sdk/test/ci/types/Duration.test.ts: -------------------------------------------------------------------------------- 1 | import { Duration } from '../../../src/index.js'; 2 | 3 | describe('fromString', () => { 4 | test('Parsing simple valid string', () => { 5 | const duration = Duration.fromString('100ms'); 6 | const value = Number(Duration.toMillis(duration)); 7 | expect(value).toBe(100); 8 | }); 9 | 10 | test('Parsing valid string', () => { 11 | const duration = Duration.fromString('10d 1h 2m 7s'); 12 | const value = Number(Duration.toMillis(duration)); 13 | expect(value).toBe(867_727_000); 14 | }); 15 | 16 | test('Fails when using invalid unit for a measure', () => { 17 | expect(() => { 18 | Duration.fromString('1w 10d'); 19 | }).toThrow(); 20 | }); 21 | 22 | test('Fails when using decimals in a measure', () => { 23 | expect(() => { 24 | Duration.fromString('10.0d'); 25 | }).toThrow(); 26 | }); 27 | 28 | test('Fails when using negative numbers in a measure', () => { 29 | expect(() => { 30 | Duration.fromString('-10d'); 31 | }).toThrow(); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /packages/sdk/test/ci/util.test.ts: -------------------------------------------------------------------------------- 1 | import { readFileSync } from 'fs'; 2 | 3 | import { getEmbeddedModuleSchema } from '../../src/index.js'; 4 | import { stringToInt } from '../../src/util.js'; 5 | 6 | test('stringToInt transforms chosen field, but not others', () => { 7 | const keysToTransform = ['a']; 8 | const input = '{ "a":"90071992547409910", "b":"90071992547409911", "aa":"90071992547409912"}'; 9 | const transformed = stringToInt(input, keysToTransform); 10 | expect(transformed).toEqual('{ "a":90071992547409910, "b":"90071992547409911", "aa":"90071992547409912"}'); 11 | }); 12 | 13 | test('stringToInt transforms multiple fields', () => { 14 | const keysToTransform = ['a', 'b']; 15 | const input = '{ "a":"90071992547409910", "b":"90071992547409911", "aa":{"a":"12071992547409910","c":"1"}}'; 16 | const transformed = stringToInt(input, keysToTransform); 17 | expect(transformed).toEqual( 18 | '{ "a":90071992547409910, "b":90071992547409911, "aa":{"a":12071992547409910,"c":"1"}}' 19 | ); 20 | }); 21 | 22 | test('stringToInt will not change the string if no keys match', () => { 23 | const keysToTransform = ['d', 'aaa']; 24 | const input = '{ "a":"90071992547409910", "b":"90071992547409911", "aa":{"a":"12071992547409910","c":"1"}}'; 25 | const transformed = stringToInt(input, keysToTransform); 26 | expect(transformed).toEqual(input); 27 | }); 28 | 29 | test('Embedded schema is the same as a seperate schema file', async () => { 30 | const versionedWasmModule = readFileSync('test/ci/resources/icecream-with-schema.wasm'); 31 | // Strip module version information 32 | const wasmModule = versionedWasmModule.subarray(8); 33 | 34 | const seperateSchema = readFileSync('test/ci/resources/icecream-schema.bin'); 35 | const embeddedSchema = await getEmbeddedModuleSchema({ 36 | source: wasmModule, 37 | version: 1, 38 | }); 39 | 40 | expect(new Uint8Array(seperateSchema)).toEqual(new Uint8Array(embeddedSchema!.buffer)); 41 | }); 42 | -------------------------------------------------------------------------------- /packages/sdk/test/client/cis0.test.ts: -------------------------------------------------------------------------------- 1 | import { CIS0, ContractAddress, cis0Supports } from '../../src/index.js'; 2 | import { getNodeClientV2 as getNodeClient } from './testHelpers.js'; 3 | 4 | const client = getNodeClient(); 5 | 6 | test('cis0Supports', async () => { 7 | const result = await cis0Supports(client, ContractAddress.create(3496), 'CIS-0'); 8 | expect(result?.type).toEqual(CIS0.SupportType.Support); 9 | 10 | const resultMulti = await cis0Supports(client, ContractAddress.create(3496), ['CIS-0', 'CIS-2']); 11 | 12 | resultMulti?.map((r) => expect(r.type)).forEach((e) => e.toEqual(CIS0.SupportType.Support)); 13 | 14 | const resultCIS1 = await cis0Supports(client, ContractAddress.create(3496), 'CIS-1'); 15 | expect(resultCIS1?.type).toEqual(CIS0.SupportType.NoSupport); 16 | 17 | const resultArb = await cis0Supports(client, ContractAddress.create(3496), 'NON-STANDARD-ID-123'); 18 | expect(resultArb?.type).toEqual(CIS0.SupportType.NoSupport); 19 | }); 20 | 21 | test('cis0Supports throws on non cis-0', async () => { 22 | const result = await cis0Supports(client, ContractAddress.create(3494), 'CIS-0'); 23 | expect(result).toBe(undefined); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/sdk/test/client/cis3Util.test.ts: -------------------------------------------------------------------------------- 1 | import { CIS3, deserializeCIS3Event, deserializeCIS3EventsFromSummary } from '../../src/cis3/util.js'; 2 | import { AccountAddress, BlockItemSummary, ContractEvent, TransactionHash } from '../../src/index.js'; 3 | import { getNodeClientV2 } from './testHelpers.js'; 4 | 5 | const TRANSACTION_HASH = TransactionHash.fromHexString( 6 | 'bbbb4dbac785210092ccbe3692d166b858bb0edc05068c2346a0446d05d3695b' 7 | ); 8 | const SPONSOREE = AccountAddress.fromBase58('4NgCvVSCuCyHkALqbAnSX3QEC7zrfoZbig7X3ePMpk8iLod6Yj'); 9 | 10 | async function getBlockItemSummary(): Promise { 11 | const nodeClient = getNodeClientV2(); 12 | const bi = await nodeClient.waitForTransactionFinalization(TRANSACTION_HASH); 13 | return bi.summary; 14 | } 15 | 16 | test('CIS3 nonce events are deserialized correctly', async () => { 17 | const bi = await getBlockItemSummary(); 18 | const events = deserializeCIS3EventsFromSummary(bi); 19 | const expected: CIS3.NonceEvent = { 20 | type: CIS3.EventType.Nonce, 21 | nonce: 0n, 22 | sponsoree: SPONSOREE, 23 | }; 24 | expect(events).toStrictEqual([expected]); 25 | }); 26 | 27 | test('Custom CIS3 events are deserialized correctly', async () => { 28 | const data = Uint8Array.from([249, 1, 2, 3]); 29 | const event = ContractEvent.fromBuffer(data); 30 | const deserializedCustomEvent = deserializeCIS3Event(event); 31 | const expectedDeserializedCustomEvent: CIS3.CustomEvent = { 32 | type: CIS3.EventType.Custom, 33 | data, 34 | }; 35 | expect(deserializedCustomEvent).toEqual(expectedDeserializedCustomEvent); 36 | }); 37 | -------------------------------------------------------------------------------- /packages/sdk/test/client/deserialization.test.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs'; 2 | 3 | import { 4 | BlockHash, 5 | ContractAddress, 6 | ContractName, 7 | deserializeContractState, 8 | isInstanceInfoV0, 9 | } from '../../src/index.js'; 10 | import { getNodeClientV2 as getNodeClient } from './testHelpers.js'; 11 | 12 | const client = getNodeClient(); 13 | 14 | // TODO: find a new two-step-transfer instance / or another V0 contract with state 15 | test.skip('Deserialize state with schema from file (two-step-transfer)', async () => { 16 | const blockHash = 'fad0981b0424c6e1af746a39667628861481ac225f90decd233980311c2e19cb'; 17 | const contractAddress = ContractAddress.create(1646); 18 | 19 | const instanceInfo = await client.getInstanceInfo(contractAddress, BlockHash.fromHexString(blockHash)); 20 | if (!instanceInfo) { 21 | throw new Error('The instance info should exist for the provided block hash.'); 22 | } 23 | 24 | if (!isInstanceInfoV0(instanceInfo)) { 25 | throw new Error('The contract should be version 0, but was not.'); 26 | } 27 | 28 | const schema = Buffer.from(fs.readFileSync('./test/client/resources/two-step-transfer-schema.bin')); 29 | const state = deserializeContractState( 30 | ContractName.fromStringUnchecked('two-step-transfer'), 31 | schema, 32 | instanceInfo.model 33 | ); 34 | expect(state.init_params.transfer_agreement_threshold).toBe(2); 35 | expect(state.init_params.account_holders.length).toBe(2); 36 | expect(state.init_params.account_holders[0]).toBe('3Y1RLgi5pW3x96xZ7CiDiKsTL9huU92qn6mfxpebwmtkeku8ry'); 37 | expect(state.init_params.account_holders[1]).toBe('4EdBeGmpnQZWxaiig7FGEhWwmJurYmYsPWXo6owMDxA7ZtJMMH'); 38 | expect(state.init_params.transfer_request_ttl).toBe('0d 0h 0m 0s 0ms'); 39 | expect(state.requests.length).toBe(0); 40 | }); 41 | -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/cis2-block-item-summary.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/packages/sdk/test/client/resources/cis2-block-item-summary.bin -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/cis4-block-item-summary.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/packages/sdk/test/client/resources/cis4-block-item-summary.bin -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/piggy_bank.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Concordium/concordium-node-sdk-js/db36a2342f9942c728542e16dea6920160c1cd1f/packages/sdk/test/client/resources/piggy_bank.wasm -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/schemaFiles/schema11.bin: -------------------------------------------------------------------------------- 1 |  UserDetailsagenamecity insertAmount -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/schemaFiles/schema12.bin: -------------------------------------------------------------------------------- 1 |  MarkSheetmaths chemistryphysics insertAmount -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/schemaFiles/schema14.bin: -------------------------------------------------------------------------------- 1 |  UserAddress  insertAmount -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/schemaFiles/schema15.bin: -------------------------------------------------------------------------------- 1 |  2 | UserAmount 3 |  insertAmount -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/schemaFiles/schema16.bin: -------------------------------------------------------------------------------- 1 | CAddress  insertAmount -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/schemaFiles/schema17.bin: -------------------------------------------------------------------------------- 1 | ContractForTime  insertAmount -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/schemaFiles/schema18.bin: -------------------------------------------------------------------------------- 1 | ContractForDuration insertAmount -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/schemaFiles/schema21.bin: -------------------------------------------------------------------------------- 1 | INDBankStringArray insertAmount insertAmount1 insertAmount2 insertAmount3 insertAmount4 insertAmount5 insertAmount6 insertAmount7 -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/schemaFiles/schema30.bin: -------------------------------------------------------------------------------- 1 | SampleContract1agenamecitycountry nicknames insertAmount insertAmount1agenamecitycountry nicknames insertAmount2 insertAmount3 insertAmount4 -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/schemaFiles/schema31.bin: -------------------------------------------------------------------------------- 1 | SimpleU8 insertAmount -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/schemaFiles/schema32.bin: -------------------------------------------------------------------------------- 1 |  2 | SimpleEnumIntactSmashed insertAmount -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/schemaFiles/schema33.bin: -------------------------------------------------------------------------------- 1 |  ComplexEnum2RequestTransfer 2 |  insertAmount -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/schemaFiles/schema34.bin: -------------------------------------------------------------------------------- 1 |  ListContract insertAmount -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/schemaFiles/schema35.bin: -------------------------------------------------------------------------------- 1 |  ComplexEnum1RequestTransfer 2 |  insertAmountIntactSmashed -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/schemaFiles/schema6.bin: -------------------------------------------------------------------------------- 1 |  2 | INDBankU83 insertAmount insertAmount1 insertAmount2 insertAmount3 insertAmount4 insertAmount5 insertAmount6 insertAmount7 -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/schemaFiles/schema8.bin: -------------------------------------------------------------------------------- 1 |  INDBankBool1 insertAmount insertAmount1 insertAmount2 insertAmount3 insertAmount4 insertAmount5 insertAmount6 insertAmount7 -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/schemaFiles/schema_test.bin: -------------------------------------------------------------------------------- 1 |  schema-tests_bools_u8s_u16s_u32s_u64s_u128s_i8s_i16s_i32s_i64 s_i128s_amount 2 | s_account_address s_contract_address s_timestamp 3 | s_durations_pair s_list s_setabs_mapabs_array s_struct first_field second_field third_fields_enumABFXCc1 c2s_strings_contract_names_receive_names_bools_u8s_u16s_u32s_u64s_u128s_i8s_i16s_i32s_i64 s_i128s_amount 4 | s_account_address s_contract_address s_timestamp 5 | s_durations_pair s_list s_setabs_mapabs_array s_struct first_field second_field third_fields_enumABFXCc1 c2s_strings_contract_names_receive_name -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/schemaFiles/schema_two_step_transfer.bin: -------------------------------------------------------------------------------- 1 | two-step-transfer init_paramsaccount_holders transfer_agreement_thresholdtransfer_request_ttlrequeststransfer_amount 2 | target_account times_out_at 3 | supporters account_holders transfer_agreement_thresholdtransfer_request_ttlreceiveRequestTransfer 4 | SupportTransfer 5 | -------------------------------------------------------------------------------- /packages/sdk/test/client/resources/two-step-transfer-schema.bin: -------------------------------------------------------------------------------- 1 | two-step-transfer init_paramsaccount_holders transfer_agreement_thresholdtransfer_request_ttlrequeststransfer_amount 2 | target_account times_out_at 3 | supporters account_holders transfer_agreement_thresholdtransfer_request_ttlreceiveRequestTransfer 4 | SupportTransfer 5 | -------------------------------------------------------------------------------- /packages/sdk/test/globals.ts: -------------------------------------------------------------------------------- 1 | declare const __ENV__: 'node' | 'react-native' | 'web'; 2 | export const testEnvironment = __ENV__; 3 | -------------------------------------------------------------------------------- /packages/sdk/test/setup.web.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | // eslint-disable-next-line import/no-extraneous-dependencies 3 | import * as ed from '@concordium/web-sdk/shims/ed25519'; 4 | // self-reference doesn't work in eslint import resolver 5 | import { sha512 } from '@noble/hashes/sha512'; 6 | import 'isomorphic-fetch'; 7 | import { TextDecoder, TextEncoder } from 'node:util'; 8 | 9 | (global as any).TextEncoder = TextEncoder; 10 | (global as any).TextDecoder = TextDecoder; 11 | 12 | ed.etc.sha512Async = (...m) => Promise.resolve(sha512(ed.etc.concatBytes(...m))); 13 | -------------------------------------------------------------------------------- /packages/sdk/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["src/**/*"], 4 | "compilerOptions": { 5 | "allowImportingTsExtensions": false, 6 | "rootDir": "./src", 7 | "outDir": "./lib/esm" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/sdk/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-base.json", 3 | "compilerOptions": { 4 | "lib": [ 5 | "ES2020", 6 | "DOM" // To get WebAssembly type. 7 | ], 8 | "allowImportingTsExtensions": true 9 | }, 10 | "include": [ 11 | "src/**/*", 12 | "polyfill/**/*", 13 | "scripts/**/*", 14 | "test/**/*", 15 | "webpack.config.ts", 16 | "jest.config.react-native.ts", 17 | "jest.config.web.ts", 18 | "jest.config.ts" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /packages/wallet-connectors/.gitignore: -------------------------------------------------------------------------------- 1 | /dist/ 2 | /node_modules/ 3 | -------------------------------------------------------------------------------- /packages/wallet-connectors/.prettierignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | -------------------------------------------------------------------------------- /packages/wallet-connectors/jest.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from '@jest/types'; 2 | 3 | const esModules = ['@concordium/web-sdk', '@noble/ed25519'].join('|'); 4 | 5 | const config: Config.InitialOptions = { 6 | preset: 'ts-jest/presets/js-with-ts-esm', 7 | transformIgnorePatterns: [`node_modules/(?!${esModules})`], 8 | transform: { 9 | '^.+\\.tsx?$': [ 10 | 'ts-jest', 11 | { 12 | tsconfig: 'tsconfig.test.json', 13 | }, 14 | ], 15 | }, 16 | }; 17 | 18 | export default config; 19 | -------------------------------------------------------------------------------- /packages/wallet-connectors/src/error.ts: -------------------------------------------------------------------------------- 1 | export class UnreachableCaseError extends Error { 2 | constructor( 3 | readonly type: string, 4 | readonly val: never 5 | ) { 6 | super(`invalid ${type} kind '${val}`); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/wallet-connectors/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './constants'; 2 | export * from './WalletConnection'; 3 | export * from './WalletConnect'; 4 | export * from './BrowserWallet'; 5 | -------------------------------------------------------------------------------- /packages/wallet-connectors/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/recommended/tsconfig.json", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "declarationMap": true, 6 | "module": "ES2020", 7 | "moduleResolution": "bundler", 8 | "sourceMap": true, 9 | "outDir": "./dist" 10 | }, 11 | "include": ["./src"] 12 | } 13 | -------------------------------------------------------------------------------- /packages/wallet-connectors/tsconfig.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "target": "ES2020", 5 | "allowJs": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | edition="2018" 2 | combine_control_expr = false 3 | wrap_comments = true 4 | brace_style = "PreferSameLine" 5 | enum_discrim_align_threshold = 20 6 | fn_single_line = true 7 | format_strings = true 8 | format_macro_matchers = true 9 | format_macro_bodies = true 10 | imports_granularity = "Crate" 11 | normalize_comments = true 12 | reorder_impl_items = true 13 | reorder_imports = true 14 | struct_field_align_threshold = 20 15 | trailing_semicolon = true 16 | type_punctuation_density = "Wide" 17 | use_field_init_shorthand = true 18 | use_try_shorthand = true 19 | format_code_in_doc_comments = true 20 | overflow_delimited_expr = true 21 | normalize_doc_attributes = true 22 | -------------------------------------------------------------------------------- /tsconfig-base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "lib": ["ES2020"], 5 | "module": "Node16", 6 | "declaration": true, 7 | "sourceMap": true, 8 | "moduleResolution": "Node16", 9 | "target": "ES2020", 10 | "esModuleInterop": true, 11 | "allowJs": true, 12 | "composite": true, 13 | "skipLibCheck": true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["./**/*.config.js", "./.eslintrc.cjs", "./scripts/*.js"] 3 | } 4 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": ".", 4 | "target": "ES2020", 5 | "resolveJsonModule": true, 6 | "composite": true, 7 | "strict": true, 8 | "declaration": true 9 | }, 10 | "files": [], 11 | "references": [ 12 | { 13 | "path": "./packages/sdk" 14 | } 15 | ] 16 | } 17 | --------------------------------------------------------------------------------