├── example ├── ios │ ├── Runner │ │ ├── Runner-Bridging-Header.h │ │ ├── Assets.xcassets │ │ │ ├── LaunchImage.imageset │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ ├── README.md │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ └── Contents.json │ │ ├── AppDelegate.swift │ │ ├── Base.lproj │ │ │ ├── Main.storyboard │ │ │ └── LaunchScreen.storyboard │ │ └── Info.plist │ ├── Flutter │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── AppFrameworkInfo.plist │ ├── Runner.xcodeproj │ │ └── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ ├── .gitignore │ ├── Podfile │ └── Podfile.lock ├── android │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── drawable │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ └── values │ │ │ │ │ │ └── styles.xml │ │ │ │ ├── kotlin │ │ │ │ │ └── io │ │ │ │ │ │ └── polkawallet │ │ │ │ │ │ └── www │ │ │ │ │ │ └── example │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ └── AndroidManifest.xml │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ └── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── .gitignore │ ├── settings.gradle │ └── build.gradle ├── .metadata ├── README.md ├── .gitignore ├── lib │ └── pages │ │ └── dAppPage.dart └── pubspec.yaml ├── js_api ├── .yarnrc.yml ├── src │ ├── service │ │ ├── walletconnect │ │ │ ├── v1 │ │ │ │ ├── constants │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── default.ts │ │ │ │ │ └── chains.ts │ │ │ │ └── helpers │ │ │ │ │ ├── wallet.ts │ │ │ │ │ └── api.ts │ │ │ ├── v2 │ │ │ │ ├── helpers │ │ │ │ │ └── wallet.ts │ │ │ │ └── data │ │ │ │ │ ├── RelayerRegions.ts │ │ │ │ │ ├── PolkadotData.ts │ │ │ │ │ └── EIP155Data.ts │ │ │ └── engines │ │ │ │ └── index.ts │ │ ├── assets.ts │ │ ├── multiChain.ts │ │ ├── staking │ │ │ └── inflation.ts │ │ ├── eth │ │ │ ├── account.ts │ │ │ └── settings.ts │ │ └── setting.ts │ ├── bridge.ts │ ├── utils │ │ ├── config │ │ │ ├── links │ │ │ │ ├── index.ts │ │ │ │ ├── commonwealth.ts │ │ │ │ ├── subscan.ts │ │ │ │ ├── polkascan.ts │ │ │ │ ├── subsquare.ts │ │ │ │ └── polkassembly.ts │ │ │ └── config.ts │ │ └── bip39Util.ts │ └── types │ │ └── scannerTypes.ts ├── .yarnrc ├── .gitignore ├── test │ └── index.html ├── babel.config.js ├── README.md ├── tsconfig.json └── webpack.config.js ├── js_as_extension ├── dist │ ├── index.html │ └── main.js.LICENSE.txt ├── babel.config.js ├── webpack.config.js ├── package.json └── src │ ├── index.js │ └── handlers.js ├── .gitmodules ├── .gitattributes ├── assets ├── index.html └── bridge.html ├── lib ├── api │ ├── types │ │ ├── staking │ │ │ ├── accountBondedInfo.dart │ │ │ └── ownStashInfo.dart │ │ ├── verifyResult.dart │ │ ├── parachain │ │ │ ├── bidData.dart │ │ │ ├── parasOverviewData.dart │ │ │ ├── fundData.dart │ │ │ ├── bidData.g.dart │ │ │ ├── parasOverviewData.g.dart │ │ │ ├── auctionData.dart │ │ │ ├── fundData.g.dart │ │ │ └── auctionData.g.dart │ │ ├── uosQrParseResultData.dart │ │ ├── gov │ │ │ ├── genExternalLinksParams.dart │ │ │ ├── councilInfoData.dart │ │ │ ├── genExternalLinksParams.g.dart │ │ │ ├── treasuryTipData.dart │ │ │ ├── proposalInfoData.dart │ │ │ ├── councilInfoData.g.dart │ │ │ ├── treasuryTipData.g.dart │ │ │ ├── proposalInfoData.g.dart │ │ │ └── referendumInfoData.dart │ │ ├── bridge │ │ │ ├── bridgeTxParams.dart │ │ │ ├── bridgeTxParams.g.dart │ │ │ ├── bridgeChainData.dart │ │ │ ├── bridgeTokenBalance.dart │ │ │ ├── bridgeChainData.g.dart │ │ │ └── bridgeTokenBalance.g.dart │ │ ├── networkStateData.dart │ │ ├── networkParams.dart │ │ ├── recoveryInfo.dart │ │ ├── verifyResult.g.dart │ │ ├── uosQrParseResultData.g.dart │ │ ├── addressIconData.dart │ │ ├── networkParams.g.dart │ │ ├── txData.dart │ │ ├── networkStateData.g.dart │ │ ├── addressIconData.g.dart │ │ ├── txData.g.dart │ │ ├── evmTxData.dart │ │ ├── txInfoData.dart │ │ ├── balanceData.dart │ │ ├── walletConnect │ │ │ ├── payloadData.dart │ │ │ ├── payloadData.g.dart │ │ │ └── pairingData.dart │ │ ├── txInfoData.g.dart │ │ ├── evmTxData.g.dart │ │ └── balanceData.g.dart │ ├── eth │ │ └── index.dart │ ├── apiParachain.dart │ ├── apiUOS.dart │ ├── apiSetting.dart │ ├── apiAssets.dart │ ├── apiGov2.dart │ ├── apiRecovery.dart │ ├── apiTx.dart │ ├── apiStaking.dart │ └── apiAccount.dart ├── utils │ ├── index.dart │ ├── app.dart │ └── i18n.dart ├── service │ ├── eth │ │ ├── index.dart │ │ ├── rpcApi.dart │ │ └── accountEth.dart │ ├── assets.dart │ ├── localServer.dart │ ├── parachain.dart │ ├── uos.dart │ ├── setting.dart │ ├── gov2.dart │ ├── tx.dart │ ├── recovery.dart │ ├── staking.dart │ ├── account.dart │ └── index.dart ├── plugin │ └── homeNavItem.dart ├── consts │ └── settings.dart ├── storage │ ├── types │ │ ├── ethWalletData.dart │ │ ├── keyPairData.dart │ │ ├── ethWalletData.g.dart │ │ └── keyPairData.g.dart │ └── localStorage.dart ├── webviewWithExtension │ └── types │ │ └── signExtrinsicParam.dart └── polkawallet_sdk.dart ├── .github ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md └── workflows │ ├── publish.yml │ └── dart.yml ├── .gitignore ├── .pubignore ├── test └── polkawallet_sdk_test.dart └── pubspec.yaml /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /js_api/.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | 3 | yarnPath: .yarn/releases/yarn-3.2.1.cjs 4 | -------------------------------------------------------------------------------- /js_api/src/service/walletconnect/v1/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./chains"; 2 | export * from "./default"; 3 | -------------------------------------------------------------------------------- /js_as_extension/dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "mobile-provider"] 2 | path = mobile-provider 3 | url = git@github.com:RomeroYang/mobile-provider.git 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | js_api/.yarn/releases/** binary 2 | js_api/.yarn/plugins/** binary 3 | js_api/dist/** binary 4 | assets/*.js binary 5 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /js_api/.yarnrc: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | yarn-path ".yarn/releases/yarn-1.22.19.cjs" 6 | -------------------------------------------------------------------------------- /js_api/src/service/walletconnect/v1/helpers/wallet.ts: -------------------------------------------------------------------------------- 1 | export const notifyWallet = (data: any) => { 2 | (window).send("wallet_connect_message", data); 3 | }; 4 | -------------------------------------------------------------------------------- /js_api/src/service/walletconnect/v2/helpers/wallet.ts: -------------------------------------------------------------------------------- 1 | export const notifyWallet = (data: any) => { 2 | (window).send("wallet_connect_message_v2", data); 3 | }; 4 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | # android.enableBuildCache=false -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /js_api/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | 3 | .yarn/* 4 | !.yarn/patches 5 | !.yarn/plugins 6 | !.yarn/releases 7 | !.yarn/sdks 8 | !.yarn/versions 9 | 10 | *.log 11 | 12 | src/config.local.ts 13 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polkawallet-io/sdk/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/io/polkawallet/www/example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package io.polkawallet.www.example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /assets/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

polkadot-js/api runner

8 | 9 | 10 | -------------------------------------------------------------------------------- /assets/bridge.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

polkawallet bridge js runner

8 | 9 | 10 | -------------------------------------------------------------------------------- /js_as_extension/dist/main.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */ 2 | 3 | /*! noble-secp256k1 - MIT License (c) 2019 Paul Miller (paulmillr.com) */ 4 | 5 | /*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */ 6 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | android.enableR8=true 7 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /js_api/src/bridge.ts: -------------------------------------------------------------------------------- 1 | import bridge from "./service/bridge"; 2 | 3 | // console.log will send message to MsgChannel to App 4 | function send(path: string, data: any) { 5 | console.log(JSON.stringify({ path, data })); 6 | } 7 | send("log", "bridge js loaded"); 8 | (window).send = send; 9 | 10 | (window).bridge = bridge; -------------------------------------------------------------------------------- /js_api/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/api/types/staking/accountBondedInfo.dart: -------------------------------------------------------------------------------- 1 | class AccountBondedInfo { 2 | AccountBondedInfo(this.pubKey, this.controllerId, this.stashId); 3 | final String? pubKey; 4 | // controllerId != null, means the account is a stash 5 | final String? controllerId; 6 | // stashId != null, means the account is a controller 7 | final String? stashId; 8 | } -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: bbfbf1770cca2da7c82e887e4e4af910034800b6 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /lib/utils/index.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:convert/convert.dart'; 4 | 5 | class Encrypt { 6 | static String passwordToEncryptKey(String password) { 7 | String passHex = hex.encode(utf8.encode(password)); 8 | if (passHex.length > 32) { 9 | return passHex.substring(0, 32); 10 | } 11 | return passHex.padRight(32, '0'); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /lib/utils/app.dart: -------------------------------------------------------------------------------- 1 | class AppUtils { 2 | /// The App will set this function for plugins switch between each other 3 | /// accountType(0:Substrate,1:evm) 4 | Future Function(String network, 5 | {PageRouteParams? pageRoute, int accountType})? switchNetwork; 6 | } 7 | 8 | class PageRouteParams { 9 | PageRouteParams(this.path, {this.args}); 10 | 11 | final String path; 12 | final Map? args; 13 | } 14 | -------------------------------------------------------------------------------- /js_as_extension/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | assumptions: { setPublicClassFields: true, privateFieldsAsProperties: true }, 3 | presets: [["@babel/preset-env", { modules: false }]], 4 | plugins: [ 5 | "@babel/plugin-proposal-private-methods", 6 | "@babel/plugin-proposal-class-properties", 7 | "@babel/plugin-transform-runtime", 8 | "@babel/plugin-transform-classes", 9 | "@babel/plugin-transform-modules-commonjs", 10 | ], 11 | }; 12 | -------------------------------------------------------------------------------- /lib/api/types/verifyResult.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'verifyResult.g.dart'; 4 | 5 | @JsonSerializable() 6 | class VerifyResult extends _VerifyResult { 7 | static VerifyResult fromJson(Map json) => 8 | _$VerifyResultFromJson(json); 9 | Map toJson() => _$VerifyResultToJson(this); 10 | } 11 | 12 | abstract class _VerifyResult { 13 | String? crypto; 14 | bool? isValid; 15 | } 16 | -------------------------------------------------------------------------------- /js_api/src/utils/config/links/index.ts: -------------------------------------------------------------------------------- 1 | import Commonwealth from "./commonwealth"; 2 | import Polkascan from "./polkascan"; 3 | import { PolkassemblyIo, PolkassemblyNetwork } from "./polkassembly"; 4 | import Subscan from "./subscan"; 5 | import SubSquare from "./subsquare"; 6 | 7 | const externals = { 8 | Commonwealth, 9 | Polkascan, 10 | Polkassembly: PolkassemblyIo, 11 | PolkassemblyNetwork, 12 | Subscan, 13 | SubSquare, 14 | }; 15 | 16 | export default externals; 17 | -------------------------------------------------------------------------------- /lib/service/eth/index.dart: -------------------------------------------------------------------------------- 1 | import 'package:polkawallet_sdk/service/eth/accountEth.dart'; 2 | import 'package:polkawallet_sdk/service/eth/keyringEth.dart'; 3 | import 'package:polkawallet_sdk/service/index.dart'; 4 | 5 | class ServiceEth { 6 | ServiceEth(SubstrateService serviceRoot) { 7 | account = ServiceAccountEth(serviceRoot); 8 | keyring = ServiceKeyringEth(serviceRoot); 9 | } 10 | 11 | late ServiceAccountEth account; 12 | late ServiceKeyringEth keyring; 13 | } 14 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/api/types/parachain/bidData.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'bidData.g.dart'; 4 | 5 | @JsonSerializable() 6 | class BidData extends _BidData { 7 | static BidData fromJson(Map json) => _$BidDataFromJson(json as Map); 8 | Map toJson() => _$BidDataToJson(this); 9 | } 10 | 11 | abstract class _BidData { 12 | String? paraId; 13 | int? firstSlot; 14 | int? lastSlot; 15 | bool? isCrowdloan; 16 | dynamic value; 17 | } 18 | -------------------------------------------------------------------------------- /js_api/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | assumptions: { setPublicClassFields: true, privateFieldsAsProperties: true }, 3 | presets: [["@babel/preset-env", { modules: false, useBuiltIns: "usage", corejs: "3.33.2" }], "@babel/preset-typescript"], 4 | plugins: [ 5 | "@babel/plugin-proposal-private-methods", 6 | "@babel/plugin-proposal-class-properties", 7 | "@babel/plugin-transform-classes", 8 | "@babel/plugin-transform-runtime", 9 | ], 10 | sourceType: "unambiguous", 11 | }; 12 | -------------------------------------------------------------------------------- /js_api/src/service/assets.ts: -------------------------------------------------------------------------------- 1 | import { ApiPromise } from "@polkadot/api"; 2 | 3 | /** 4 | * get assets ids of statemine/statemint network. 5 | */ 6 | async function getAssetsAll(api: ApiPromise) { 7 | const entries = await api.query.assets.metadata.entries(); 8 | return entries 9 | .map(([{ args: [assetId] }, data]) => ({ 10 | id: assetId.toNumber(), 11 | ...data.toHuman(), 12 | })) 13 | .sort((a, b) => a.id - b.id); 14 | } 15 | 16 | export default { 17 | getAssetsAll, 18 | }; 19 | -------------------------------------------------------------------------------- /js_api/src/service/walletconnect/v1/constants/default.ts: -------------------------------------------------------------------------------- 1 | export const ETH_STANDARD_PATH = "m/44'/60'/0'/0"; 2 | 3 | export const MAINNET_CHAIN_ID = 1; 4 | export const GOERLI_CHAIN_ID = 5; 5 | export const DEFAULT_CHAIN_ID = GOERLI_CHAIN_ID; 6 | 7 | export const DEFAULT_WALLET_CLIENT = { 8 | description: "Mobile wallet for Dotsama eco.", 9 | url: "https://polkawallet.io", 10 | icons: ["https://raw.githubusercontent.com/polkawallet-io/app/master/assets/images/icon.png"], 11 | name: "Polkawallet", 12 | }; 13 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /js_api/src/types/scannerTypes.ts: -------------------------------------------------------------------------------- 1 | import { SubmittableExtrinsic } from "@polkadot/api/types"; 2 | import { SignerPayloadJSON } from "@polkadot/types/types"; 3 | 4 | export type QRSigner = { 5 | completedFramesCount: number; 6 | multipartData: any[]; 7 | multipartComplete: boolean; 8 | totalFrameCount: number; 9 | latestFrame: number; 10 | missedFrames: any[]; 11 | unsignedData: any; 12 | }; 13 | 14 | export type QRSubmittable = { 15 | tx: SubmittableExtrinsic<"promise">; 16 | payload: SignerPayloadJSON; 17 | }; 18 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /lib/api/eth/index.dart: -------------------------------------------------------------------------------- 1 | import 'package:polkawallet_sdk/api/api.dart'; 2 | import 'package:polkawallet_sdk/api/eth/apiAccountEth.dart'; 3 | import 'package:polkawallet_sdk/api/eth/apiKeyringEth.dart'; 4 | import 'package:polkawallet_sdk/service/eth/index.dart'; 5 | 6 | class ApiEth { 7 | ApiEth(PolkawalletApi apiRoot, ServiceEth service) { 8 | account = ApiAccountEth(apiRoot, service.account); 9 | keyring = ApiKeyringEth(apiRoot, service.keyring); 10 | } 11 | 12 | late ApiAccountEth account; 13 | late ApiKeyringEth keyring; 14 | } 15 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/api/types/uosQrParseResultData.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'uosQrParseResultData.g.dart'; 4 | 5 | @JsonSerializable() 6 | class UosQrParseResultData extends _UosQrParseResultData { 7 | static UosQrParseResultData fromJson(Map json) => 8 | _$UosQrParseResultDataFromJson(json); 9 | Map toJson() => _$UosQrParseResultDataToJson(this); 10 | } 11 | 12 | abstract class _UosQrParseResultData { 13 | String? error; 14 | String? signer; 15 | String? genesisHash; 16 | } 17 | -------------------------------------------------------------------------------- /lib/api/types/gov/genExternalLinksParams.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'genExternalLinksParams.g.dart'; 4 | 5 | @JsonSerializable() 6 | class GenExternalLinksParams extends _GenExternalLinksParams { 7 | static GenExternalLinksParams fromJson(Map json) => 8 | _$GenExternalLinksParamsFromJson(json); 9 | Map toJson() => _$GenExternalLinksParamsToJson(this); 10 | } 11 | 12 | class _GenExternalLinksParams { 13 | String? data; 14 | String? hash; 15 | String? type; 16 | bool? withShort; 17 | } 18 | -------------------------------------------------------------------------------- /lib/api/types/parachain/parasOverviewData.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'parasOverviewData.g.dart'; 4 | 5 | @JsonSerializable(explicitToJson: true) 6 | class ParasOverviewData extends _ParasOverviewData { 7 | static ParasOverviewData fromJson(Map json) => 8 | _$ParasOverviewDataFromJson(json as Map); 9 | Map toJson() => _$ParasOverviewDataToJson(this); 10 | } 11 | 12 | abstract class _ParasOverviewData { 13 | int parasCount = 0; 14 | int currentLease = 0; 15 | int leaseLength = 0; 16 | int leaseProgress = 0; 17 | } 18 | -------------------------------------------------------------------------------- /lib/service/eth/rpcApi.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:http/http.dart'; 4 | 5 | const post_headers = {"Content-type": "application/json", "Accept": "*/*"}; 6 | 7 | class EvmRpcApi { 8 | static Future getRpcCall(String endpoint, Map payload) async { 9 | final url = '$endpoint'; 10 | try { 11 | final res = await post(Uri.parse(url), 12 | body: jsonEncode(payload), headers: post_headers); 13 | return jsonDecode(utf8.decode(res.bodyBytes)) as Map; 14 | } catch (err) { 15 | print(err); 16 | return {}; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # example 2 | 3 | polkawallet_sdk_example. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /lib/api/types/bridge/bridgeTxParams.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'bridgeTxParams.g.dart'; 4 | 5 | @JsonSerializable() 6 | class BridgeTxParams { 7 | String module; 8 | String call; 9 | List params; 10 | String txHex; 11 | BridgeTxParams({ 12 | required this.module, 13 | required this.call, 14 | required this.params, 15 | required this.txHex, 16 | }); 17 | 18 | static BridgeTxParams fromJson(Map json) => 19 | _$BridgeTxParamsFromJson(json); 20 | Map toJson() => _$BridgeTxParamsToJson(this); 21 | } 22 | -------------------------------------------------------------------------------- /lib/api/types/networkStateData.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'networkStateData.g.dart'; 4 | 5 | @JsonSerializable() 6 | class NetworkStateData extends _NetworkStateData { 7 | static NetworkStateData fromJson(Map json) => 8 | _$NetworkStateDataFromJson(json); 9 | Map toJson() => _$NetworkStateDataToJson(this); 10 | } 11 | 12 | abstract class _NetworkStateData { 13 | int? ss58Format = 0; 14 | List? tokenDecimals = [12]; 15 | List? tokenSymbol; 16 | String? name = ''; 17 | String? genesisHash = ''; 18 | } 19 | -------------------------------------------------------------------------------- /lib/api/types/parachain/fundData.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'fundData.g.dart'; 4 | 5 | @JsonSerializable() 6 | class FundData extends _FundData { 7 | static FundData fromJson(Map json) => 8 | _$FundDataFromJson(json as Map); 9 | Map toJson() => _$FundDataToJson(this); 10 | } 11 | 12 | abstract class _FundData { 13 | String paraId = ''; 14 | dynamic cap = ''; 15 | dynamic value = ''; 16 | dynamic end = ''; 17 | int firstSlot = 0; 18 | int lastSlot = 0; 19 | bool isWinner = false; 20 | bool isCapped = false; 21 | bool isEnded = false; 22 | } 23 | -------------------------------------------------------------------------------- /lib/api/types/networkParams.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'networkParams.g.dart'; 4 | 5 | @JsonSerializable() 6 | class NetworkParams extends _NetworkParams { 7 | static NetworkParams fromJson(Map json) => 8 | _$NetworkParamsFromJson(json); 9 | Map toJson() => _$NetworkParamsToJson(this); 10 | } 11 | 12 | abstract class _NetworkParams { 13 | String? name = ''; 14 | String? endpoint = ''; 15 | int? ss58 = 0; 16 | String? chainId = ''; 17 | 18 | /// networkType = 'substrate' or 'ethereum' 19 | String? networkType = 'substrate'; 20 | } 21 | -------------------------------------------------------------------------------- /lib/api/types/recoveryInfo.dart: -------------------------------------------------------------------------------- 1 | class RecoveryInfo extends _RecoveryInfo { 2 | static RecoveryInfo fromJson(Map json) { 3 | final info = RecoveryInfo(); 4 | info.address = json['address']; 5 | info.delayPeriod = json['delayPeriod']; 6 | info.threshold = json['threshold']; 7 | info.friends = List.from(json['friends'] ?? []); 8 | info.deposit = BigInt.parse((json['deposit'] ?? 0).toString()); 9 | return info; 10 | } 11 | } 12 | 13 | abstract class _RecoveryInfo { 14 | String? address; 15 | int? delayPeriod; 16 | int? threshold; 17 | List? friends; 18 | BigInt? deposit; 19 | } 20 | -------------------------------------------------------------------------------- /lib/api/types/verifyResult.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'verifyResult.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | VerifyResult _$VerifyResultFromJson(Map json) => VerifyResult() 10 | ..crypto = json['crypto'] as String? 11 | ..isValid = json['isValid'] as bool?; 12 | 13 | Map _$VerifyResultToJson(VerifyResult instance) => 14 | { 15 | 'crypto': instance.crypto, 16 | 'isValid': instance.isValid, 17 | }; 18 | -------------------------------------------------------------------------------- /js_api/src/service/walletconnect/v2/data/RelayerRegions.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Types 3 | */ 4 | 5 | type RelayerType = { 6 | value: string 7 | label: string 8 | } 9 | 10 | /** 11 | * Relayer Regions 12 | */ 13 | export const REGIONALIZED_RELAYER_ENDPOINTS: RelayerType[] = [ 14 | { 15 | value: 'wss://relay.walletconnect.com', 16 | label: 'Default' 17 | }, 18 | 19 | { 20 | value: 'wss://us-east-1.relay.walletconnect.com/', 21 | label: 'US' 22 | }, 23 | { 24 | value: 'wss://eu-central-1.relay.walletconnect.com/', 25 | label: 'EU' 26 | }, 27 | { 28 | value: 'wss://ap-southeast-1.relay.walletconnect.com/', 29 | label: 'Asia Pacific' 30 | } 31 | ] 32 | -------------------------------------------------------------------------------- /js_api/src/utils/config/links/commonwealth.ts: -------------------------------------------------------------------------------- 1 | const HASH_PATHS = ["proposal/councilmotion"]; 2 | 3 | export default { 4 | chains: { 5 | Edgeware: "edgeware", 6 | Kusama: "kusama", 7 | "Kusama CC3": "kusama", 8 | }, 9 | create: (chain: string, path: string, data: any, hash: string) => 10 | `https://commonwealth.im/${chain}/${path}/${HASH_PATHS.includes(path) ? hash || "" : data.toString()}`, 11 | isActive: true, 12 | paths: { 13 | council: "proposal/councilmotion", 14 | proposal: "proposal/democracyproposal", 15 | referendum: "proposal/referendum", 16 | treasury: "proposal/treasuryproposal", 17 | }, 18 | url: "https://commonwealth.im/", 19 | }; 20 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /lib/service/assets.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:polkawallet_sdk/service/index.dart'; 4 | 5 | class ServiceAssets { 6 | ServiceAssets(this.serviceRoot); 7 | 8 | final SubstrateService serviceRoot; 9 | 10 | Future getAssetsAll() async { 11 | final dynamic res = 12 | await serviceRoot.webView!.evalJavascript('assets.getAssetsAll(api)'); 13 | return res; 14 | } 15 | 16 | Future queryAssetsBalances(List ids, String address) async { 17 | final List res = await serviceRoot.webView!.evalJavascript('Promise.all([' 18 | '${ids.map((e) => 'api.query.assets.account($e, "$address")').join(',')}' 19 | '])'); 20 | return res; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /js_api/src/utils/config/links/subscan.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | chains: { 3 | Acala: "acala", 4 | Karura: "karura", 5 | Kusama: "kusama", 6 | "Kusama CC3": "kusama", 7 | Polkadot: "polkadot", 8 | "Polkadot CC1": "polkadot-cc1", 9 | Westend: "westend", 10 | }, 11 | create: (chain: string, path: string, data: any) => `https://${chain}.subscan.io/${path}/${data.toString()}`, 12 | isActive: true, 13 | paths: { 14 | address: "account", 15 | block: "block", 16 | council: "council", 17 | extrinsic: "extrinsic", 18 | proposal: "democracy_proposal", 19 | referendum: "referenda", 20 | techcomm: "tech", 21 | treasury: "treasury", 22 | }, 23 | url: "https://subscan.io/", 24 | }; 25 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.6.10' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:4.1.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /js_api/README.md: -------------------------------------------------------------------------------- 1 | # js_api 2 | 3 | Wrap `@polkadot-js/api` to provide APIs for polkawallet/sdk. 4 | 5 | @polkadot-js/api: ^7.9.1 6 | 7 | ## build & test 8 | 9 | To build: 10 | 11 | ```bash 12 | yarn install 13 | yarn run build 14 | ``` 15 | 16 | To test: 17 | open `./test/index.html` in chrome. 18 | open chrome dev console and run `runTests().then(console.log)` 19 | 20 | ### `polkadot-js/api` hack 21 | 22 | 1. remove `connectWithRetry()` in `node_modules/@polkadot/rpc-provider/ws/index.js` to avoid auto-connect. 23 | 2. replace value of `packageInfo.path` in `node_modules/@polkadot/api/packageInfo.js` to avoid `Invalid URL` issue in webview. 24 | 3. lock `bn.js: 4.12.0` to avoid [this issue](https://github.com/polkadot-js/api/issues/4024). 25 | -------------------------------------------------------------------------------- /js_api/src/utils/bip39Util.ts: -------------------------------------------------------------------------------- 1 | import { entropyToMnemonic } from "bip39"; 2 | import crypto from "crypto-browserify"; 3 | 4 | const STRENGTH_MAP = { 5 | 12: 16 * 8, 6 | 15: 20 * 8, 7 | 18: 24 * 8, 8 | 21: 28 * 8, 9 | 24: 32 * 8, 10 | }; 11 | 12 | const seedGenerate = (words = 12) => { 13 | const strength = STRENGTH_MAP[words]; 14 | return crypto.randomBytes(strength / 8); 15 | }; 16 | 17 | const seedToMnemonic = (seed: any) => { 18 | return entropyToMnemonic(seed); 19 | }; 20 | 21 | const mnemonicGenerate = (words = 12) => { 22 | const strength = STRENGTH_MAP[words]; 23 | const entropy = crypto.randomBytes(strength / 8); 24 | return entropyToMnemonic(entropy); 25 | }; 26 | 27 | export { mnemonicGenerate, seedGenerate, seedToMnemonic }; 28 | -------------------------------------------------------------------------------- /lib/api/types/gov/councilInfoData.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'councilInfoData.g.dart'; 4 | 5 | @JsonSerializable() 6 | class CouncilInfoData extends _CouncilInfoData { 7 | static CouncilInfoData fromJson(Map json) => 8 | _$CouncilInfoDataFromJson(json); 9 | Map toJson() => _$CouncilInfoDataToJson(this); 10 | } 11 | 12 | abstract class _CouncilInfoData { 13 | String? desiredSeats; // hex string 14 | String? termDuration; // hex string 15 | String? votingBond; // hex string 16 | 17 | List>? members; 18 | List>? runnersUp; 19 | List? candidates; 20 | 21 | String? candidateCount; // hex string 22 | String? candidacyBond; // hex string 23 | } 24 | -------------------------------------------------------------------------------- /js_api/src/utils/config/links/polkascan.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | chains: { 3 | // 'Centrifuge Mainnet': 'centrifuge', 4 | // Edgeware: 'edgeware', 5 | // Kulupu: 'kulupu', 6 | Kusama: "kusama", 7 | Polkadot: "polkadot", 8 | "Polkadot CC1": "polkadot-cc1", 9 | }, 10 | create: (chain: string, path: string, data: any) => 11 | `https://polkascan.io/${chain}/${path}/${data.toString()}`, 12 | isActive: true, 13 | paths: { 14 | address: "account", 15 | block: "block", 16 | council: "council/motion", 17 | extrinsic: "transaction", 18 | proposal: "democracy/proposal", 19 | referendum: "democracy/referendum", 20 | techcomm: "techcomm/proposal", 21 | treasury: "treasury/proposal", 22 | }, 23 | url: "https://polkascan.io/", 24 | }; 25 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish to pub.dev 2 | 3 | on: 4 | release: 5 | types: [released] 6 | branches: 7 | - master 8 | 9 | jobs: 10 | publish: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | - name: Install Flutter 15 | uses: subosito/flutter-action@v2 16 | with: 17 | flutter-version: '3.7.7' 18 | - name: Install dependencies 19 | run: flutter pub get 20 | # - name: Check Publish Warnings 21 | # run: dart pub publish --dry-run 22 | - name: Publish 23 | uses: k-paxian/dart-package-publisher@v1.5.1 24 | with: 25 | credentialJson: ${{ secrets.CREDENTIAL_JSON }} 26 | flutter: true 27 | skipTests: true 28 | force: true 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Smartphone (please complete the following information):** 27 | - Device: [e.g. iPhone6] 28 | - OS: [e.g. iOS8.1] 29 | - Version [e.g. 1.0.1] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /lib/plugin/homeNavItem.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | 3 | /// Define the widget used in polkawallet app home page. 4 | class HomeNavItem { 5 | HomeNavItem({ 6 | required this.text, 7 | required this.content, 8 | this.icon, 9 | this.iconActive, 10 | this.isAdapter = false, 11 | this.onTap, 12 | }); 13 | 14 | /// Text display in BottomNavBar. 15 | final String text; 16 | 17 | /// Icon display in BottomNavBar(Have been abandoned). 18 | final Widget? icon; 19 | 20 | /// Icon display in BottomNavBar(Have been abandoned). 21 | final Widget? iconActive; 22 | 23 | /// Page content for this nav item. 24 | final Widget content; 25 | 26 | /// V3 adapter 27 | final bool isAdapter; 28 | 29 | /// isAdapter=false&&Items.length>1 , To come into force 30 | Function()? onTap; 31 | } 32 | -------------------------------------------------------------------------------- /js_api/src/utils/config/config.ts: -------------------------------------------------------------------------------- 1 | import { ApiPromise } from "@polkadot/api"; 2 | import linked from "./links/index"; 3 | 4 | function _shortName(name: string) { 5 | return `${name[0]}${name[name.length - 1]}`; 6 | } 7 | 8 | export async function genLinks(api: ApiPromise, { data, hash, type, withShort }) { 9 | const systemChain = await api.rpc.system.chain(); 10 | return Object.entries(linked) 11 | .map(([name, { chains, create, isActive, paths, url }]) => { 12 | const extChain = chains[systemChain.toHuman()]; 13 | const extPath = paths[type]; 14 | 15 | if (!isActive || !extChain || !extPath) { 16 | return null; 17 | } 18 | 19 | return { 20 | name: withShort ? _shortName(name) : name, 21 | link: create(extChain, extPath, data, hash), 22 | }; 23 | }) 24 | .filter((e) => e); 25 | } 26 | -------------------------------------------------------------------------------- /lib/api/types/bridge/bridgeTxParams.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'bridgeTxParams.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | BridgeTxParams _$BridgeTxParamsFromJson(Map json) => 10 | BridgeTxParams( 11 | module: json['module'] as String, 12 | call: json['call'] as String, 13 | params: json['params'] as List, 14 | txHex: json['txHex'] as String, 15 | ); 16 | 17 | Map _$BridgeTxParamsToJson(BridgeTxParams instance) => 18 | { 19 | 'module': instance.module, 20 | 'call': instance.call, 21 | 'params': instance.params, 22 | 'txHex': instance.txHex, 23 | }; 24 | -------------------------------------------------------------------------------- /lib/api/types/uosQrParseResultData.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'uosQrParseResultData.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | UosQrParseResultData _$UosQrParseResultDataFromJson( 10 | Map json) => 11 | UosQrParseResultData() 12 | ..error = json['error'] as String? 13 | ..signer = json['signer'] as String? 14 | ..genesisHash = json['genesisHash'] as String?; 15 | 16 | Map _$UosQrParseResultDataToJson( 17 | UosQrParseResultData instance) => 18 | { 19 | 'error': instance.error, 20 | 'signer': instance.signer, 21 | 'genesisHash': instance.genesisHash, 22 | }; 23 | -------------------------------------------------------------------------------- /lib/api/types/parachain/bidData.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'bidData.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | BidData _$BidDataFromJson(Map json) => BidData() 10 | ..paraId = json['paraId'] as String? 11 | ..firstSlot = json['firstSlot'] as int? 12 | ..lastSlot = json['lastSlot'] as int? 13 | ..isCrowdloan = json['isCrowdloan'] as bool? 14 | ..value = json['value']; 15 | 16 | Map _$BidDataToJson(BidData instance) => { 17 | 'paraId': instance.paraId, 18 | 'firstSlot': instance.firstSlot, 19 | 'lastSlot': instance.lastSlot, 20 | 'isCrowdloan': instance.isCrowdloan, 21 | 'value': instance.value, 22 | }; 23 | -------------------------------------------------------------------------------- /lib/consts/settings.dart: -------------------------------------------------------------------------------- 1 | const network_ss58_map = { 2 | 'acala': 42, 3 | 'laminar': 42, 4 | 'kusama': 2, 5 | 'substrate': 42, 6 | 'polkadot': 0, 7 | }; 8 | 9 | const SigningMethodsEVM = [ 10 | "eth_sendTransaction", 11 | "eth_signTransaction", 12 | "eth_sign", 13 | "eth_signTypedData", 14 | "eth_signTypedData_v1", 15 | "eth_signTypedData_v2", 16 | "eth_signTypedData_v3", 17 | "eth_signTypedData_v4", 18 | "personal_sign", 19 | "wallet_addEthereumChain", 20 | "wallet_switchEthereumChain", 21 | "wallet_getPermissions", 22 | "wallet_requestPermissions", 23 | "wallet_registerOnboarding", 24 | "wallet_watchAsset", 25 | "wallet_scanQRCode", 26 | // wallet auth methods 27 | // "eth_chainId", 28 | "eth_requestAccounts", 29 | "eth_accounts", 30 | "metamask_getProviderState", 31 | ]; 32 | 33 | enum EVMKeyType { mnemonic, privateKey, keystore } 34 | 35 | const crypt_n = 1 << 14; 36 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Exceptions to above rules. 44 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 45 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 11.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /lib/api/types/addressIconData.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'addressIconData.g.dart'; 4 | 5 | @JsonSerializable() 6 | class AddressIconDataWithMnemonic extends _AddressIconDataWithMnemonic { 7 | static AddressIconDataWithMnemonic fromJson(Map json) => 8 | _$AddressIconDataWithMnemonicFromJson(json); 9 | Map toJson() => _$AddressIconDataWithMnemonicToJson(this); 10 | } 11 | 12 | abstract class _AddressIconDataWithMnemonic { 13 | String? mnemonic; 14 | String? address; 15 | String? svg; 16 | } 17 | 18 | @JsonSerializable() 19 | class AddressIconData extends _AddressIconData { 20 | static AddressIconData fromJson(Map json) => 21 | _$AddressIconDataFromJson(json); 22 | Map toJson() => _$AddressIconDataToJson(this); 23 | } 24 | 25 | abstract class _AddressIconData { 26 | String? address; 27 | String? svg; 28 | } 29 | -------------------------------------------------------------------------------- /lib/api/types/gov/genExternalLinksParams.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'genExternalLinksParams.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | GenExternalLinksParams _$GenExternalLinksParamsFromJson( 10 | Map json) => 11 | GenExternalLinksParams() 12 | ..data = json['data'] as String? 13 | ..hash = json['hash'] as String? 14 | ..type = json['type'] as String? 15 | ..withShort = json['withShort'] as bool?; 16 | 17 | Map _$GenExternalLinksParamsToJson( 18 | GenExternalLinksParams instance) => 19 | { 20 | 'data': instance.data, 21 | 'hash': instance.hash, 22 | 'type': instance.type, 23 | 'withShort': instance.withShort, 24 | }; 25 | -------------------------------------------------------------------------------- /lib/api/types/networkParams.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'networkParams.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | NetworkParams _$NetworkParamsFromJson(Map json) => 10 | NetworkParams() 11 | ..name = json['name'] as String? 12 | ..endpoint = json['endpoint'] as String? 13 | ..ss58 = json['ss58'] as int? 14 | ..chainId = json['chainId'] as String? 15 | ..networkType = json['networkType'] as String?; 16 | 17 | Map _$NetworkParamsToJson(NetworkParams instance) => 18 | { 19 | 'name': instance.name, 20 | 'endpoint': instance.endpoint, 21 | 'ss58': instance.ss58, 22 | 'chainId': instance.chainId, 23 | 'networkType': instance.networkType, 24 | }; 25 | -------------------------------------------------------------------------------- /js_api/src/service/walletconnect/v1/constants/chains.ts: -------------------------------------------------------------------------------- 1 | import { IChainData } from "../helpers/types"; 2 | 3 | export const SUPPORTED_CHAINS: IChainData[] = [ 4 | { 5 | name: "Ethereum Mainnet", 6 | short_name: "eth", 7 | chain: "ETH", 8 | network: "mainnet", 9 | chain_id: 1, 10 | network_id: 1, 11 | rpc_url: "https://mainnet.infura.io/v3/%API_KEY%", 12 | native_currency: { 13 | symbol: "ETH", 14 | name: "Ether", 15 | decimals: "18", 16 | contractAddress: "", 17 | balance: "", 18 | }, 19 | }, 20 | { 21 | name: "Ethereum Görli", 22 | short_name: "gor", 23 | chain: "ETH", 24 | network: "goerli", 25 | chain_id: 5, 26 | network_id: 5, 27 | rpc_url: "https://goerli.infura.io/v3/%API_KEY%", 28 | native_currency: { 29 | symbol: "ETH", 30 | name: "Ether", 31 | decimals: "18", 32 | contractAddress: "", 33 | balance: "", 34 | }, 35 | }, 36 | ]; 37 | -------------------------------------------------------------------------------- /js_as_extension/webpack.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require("webpack"); 2 | const path = require("path"); 3 | 4 | const config = { 5 | entry: "./src/index.js", 6 | output: { 7 | publicPath: path.resolve(__dirname, ""), 8 | path: path.resolve(__dirname, "dist"), 9 | filename: "main.js", 10 | }, 11 | plugins: [ 12 | new webpack.ProvidePlugin({ 13 | process: "process/browser.js", 14 | }), 15 | ], 16 | module: { 17 | rules: [ 18 | { 19 | test: /\.js$/, 20 | use: "babel-loader", 21 | exclude: /node_modules/, 22 | }, 23 | { 24 | test: /\.cjs$/, 25 | include: path.resolve(__dirname, "node_modules/@polkadot/"), 26 | use: "babel-loader", 27 | }, 28 | { 29 | test: /\.js$/, 30 | include: path.resolve(__dirname, "node_modules/@polkadot/"), 31 | use: "babel-loader", 32 | }, 33 | ], 34 | }, 35 | }; 36 | 37 | module.exports = config; 38 | -------------------------------------------------------------------------------- /lib/api/types/parachain/parasOverviewData.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'parasOverviewData.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ParasOverviewData _$ParasOverviewDataFromJson(Map json) => 10 | ParasOverviewData() 11 | ..parasCount = json['parasCount'] as int 12 | ..currentLease = json['currentLease'] as int 13 | ..leaseLength = json['leaseLength'] as int 14 | ..leaseProgress = json['leaseProgress'] as int; 15 | 16 | Map _$ParasOverviewDataToJson(ParasOverviewData instance) => 17 | { 18 | 'parasCount': instance.parasCount, 19 | 'currentLease': instance.currentLease, 20 | 'leaseLength': instance.leaseLength, 21 | 'leaseProgress': instance.leaseProgress, 22 | }; 23 | -------------------------------------------------------------------------------- /lib/api/types/txData.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'txData.g.dart'; 4 | 5 | @JsonSerializable() 6 | class TxData extends _TxData { 7 | static TxData fromJson(Map json) => _$TxDataFromJson(json); 8 | Map toJson() => _$TxDataToJson(this); 9 | } 10 | 11 | abstract class _TxData { 12 | @JsonKey(name: 'block_num') 13 | int? blockNum = 0; 14 | 15 | @JsonKey(name: 'block_timestamp') 16 | int? blockTimestamp = 0; 17 | 18 | @JsonKey(name: 'account_id') 19 | String? accountId = ""; 20 | 21 | @JsonKey(name: 'call_module') 22 | String? module = ""; 23 | 24 | @JsonKey(name: 'call_module_function') 25 | String? call = ""; 26 | 27 | @JsonKey(name: 'extrinsic_hash') 28 | String? hash = ""; 29 | 30 | @JsonKey(name: 'extrinsic_index') 31 | String? txNumber = ""; 32 | 33 | String? fee = ""; 34 | 35 | String? params = ""; 36 | 37 | int? nonce; 38 | bool? success = true; 39 | } 40 | -------------------------------------------------------------------------------- /js_api/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "target": "ES5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */, 5 | "module": "ES2015" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, 6 | "moduleResolution": "node", 7 | "lib": ["DOM"] /* Specify library files to be included in the compilation. */, 8 | "allowJs": true /* Allow javascript files to be compiled. */, 9 | "checkJs": false /* Report errors in .js files. */, 10 | "sourceMap": true /* Generates corresponding '.map' file. */, 11 | "strict": true /* Enable all strict type-checking options. */, 12 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 13 | }, 14 | "exclude": ["webpack.config.js", "dist", "test"] 15 | } 16 | -------------------------------------------------------------------------------- /lib/utils/i18n.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/foundation.dart'; 3 | 4 | class I18n { 5 | I18n(this.locale); 6 | 7 | final Locale locale; 8 | 9 | static I18n? of(BuildContext context) { 10 | return Localizations.of(context, I18n); 11 | } 12 | 13 | Map? getDic( 14 | Map>> fullDic, String module) { 15 | return fullDic[locale.languageCode]![module]; 16 | } 17 | } 18 | 19 | class AppLocalizationsDelegate extends LocalizationsDelegate { 20 | const AppLocalizationsDelegate(this.overriddenLocale); 21 | 22 | final Locale overriddenLocale; 23 | 24 | @override 25 | bool isSupported(Locale locale) => ['en', 'zh'].contains(locale.languageCode); 26 | 27 | @override 28 | Future load(Locale locale) { 29 | return SynchronousFuture(I18n(overriddenLocale)); 30 | } 31 | 32 | @override 33 | bool shouldReload(AppLocalizationsDelegate old) => true; 34 | } 35 | -------------------------------------------------------------------------------- /lib/api/types/gov/treasuryTipData.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'treasuryTipData.g.dart'; 4 | 5 | @JsonSerializable() 6 | class TreasuryTipData extends _TreasuryTipData { 7 | static TreasuryTipData fromJson(Map json) => 8 | _$TreasuryTipDataFromJson(json); 9 | Map toJson() => _$TreasuryTipDataToJson(this); 10 | } 11 | 12 | abstract class _TreasuryTipData { 13 | String? hash; 14 | String? reason; 15 | String? who; 16 | dynamic closes; 17 | String? finder; 18 | dynamic deposit; 19 | List? tips; 20 | } 21 | 22 | @JsonSerializable() 23 | class TreasuryTipItemData extends _TreasuryTipItemData { 24 | static TreasuryTipItemData fromJson(Map json) => 25 | _$TreasuryTipItemDataFromJson(json); 26 | Map toJson() => _$TreasuryTipItemDataToJson(this); 27 | } 28 | 29 | abstract class _TreasuryTipItemData { 30 | String? address; 31 | dynamic value; 32 | } 33 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /lib/storage/types/ethWalletData.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | import 'package:polkawallet_sdk/storage/types/keyPairData.dart'; 3 | 4 | part 'ethWalletData.g.dart'; 5 | 6 | @JsonSerializable() 7 | class EthWalletData extends _EthWalletData { 8 | static EthWalletData fromJson(Map json) => 9 | _$EthWalletDataFromJson(Map.from(json)); 10 | Map toJson() => _$EthWalletDataToJson(this); 11 | 12 | KeyPairData toKeyPairData() { 13 | return KeyPairData() 14 | ..address = address 15 | ..name = name 16 | ..memo = memo 17 | ..icon = icon 18 | ..pubKey = address 19 | ..observation = observation; 20 | } 21 | } 22 | 23 | abstract class _EthWalletData { 24 | String? address; 25 | String? name; 26 | String? id; 27 | int? version; 28 | 29 | Map? crypto = Map(); 30 | 31 | /// for contacts 32 | String? memo; 33 | bool? observation = false; 34 | 35 | /// address avatar in svg format 36 | String? icon; 37 | } 38 | -------------------------------------------------------------------------------- /js_api/src/service/multiChain.ts: -------------------------------------------------------------------------------- 1 | import { ApiPromise, WsProvider } from "@polkadot/api"; 2 | 3 | const nodeList: Record = { 4 | kusamaPeople: ["wss://people-kusama-rpc.dwellir.com", "wss://kusama-people-rpc.polkadot.io", "wss://ksm-rpc.stakeworld.io/people"], 5 | // people: [], 6 | }; 7 | 8 | const parachainApis: Record = {}; 9 | async function connectParachain(chainName: string): Promise { 10 | try { 11 | if (parachainApis[chainName]) { 12 | return chainName; 13 | } 14 | 15 | const wsProvider = new WsProvider(nodeList[chainName]); 16 | const res = await ApiPromise.create({ 17 | provider: wsProvider, 18 | }); 19 | 20 | parachainApis[chainName] = res; 21 | 22 | return chainName; 23 | } catch (err) { 24 | console.error(`connect parachain ${chainName} failed:`, err); 25 | return undefined; 26 | } 27 | } 28 | 29 | function getParachainApi(chainName: number): ApiPromise | undefined { 30 | return parachainApis[chainName]; 31 | } 32 | 33 | export default { connectParachain, getParachainApi }; 34 | -------------------------------------------------------------------------------- /js_api/src/utils/config/links/subsquare.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | chains: { 3 | Acala: "acala", 4 | Altair: "altair", 5 | Basilisk: "basilisk", 6 | Bifrost: "bifrost", 7 | Centrifuge: "centrifuge", 8 | Crust: "crust", 9 | "Darwinia Crab": "crab", 10 | HydraDX: "hydradx", 11 | Interlay: "interlay", 12 | Karura: "karura", 13 | Khala: "khala", 14 | Kusama: "kusama", 15 | Litmus: "litmus", 16 | Phala: "phala", 17 | Polkadot: "polkadot", 18 | Rococo: "rococo", 19 | "Turing Network": "turing", 20 | Zeitgeist: "zeitgeist", 21 | kintsugi: "kintsugi", 22 | }, 23 | create: (chain: string, path: string, data: any): string => `https://${chain}.subsquare.io/${path}/${data.toString()}`, 24 | isActive: true, 25 | paths: { 26 | bounty: "treasury/bounty", 27 | council: "council/motion", 28 | proposal: "democracy/proposal", 29 | referendum: "democracy/referendum", 30 | referenda: "referenda/referendum", 31 | tip: "treasury/tip", 32 | treasury: "treasury/proposal", 33 | }, 34 | url: "https://subsquare.io/", 35 | }; 36 | -------------------------------------------------------------------------------- /lib/api/types/gov/proposalInfoData.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | import 'package:polkawallet_sdk/api/types/gov/treasuryOverviewData.dart'; 3 | 4 | part 'proposalInfoData.g.dart'; 5 | 6 | @JsonSerializable() 7 | class ProposalInfoData extends _ProposalInfoData { 8 | static ProposalInfoData fromJson(Map json) => 9 | _$ProposalInfoDataFromJson(json); 10 | Map toJson() => _$ProposalInfoDataToJson(this); 11 | } 12 | 13 | abstract class _ProposalInfoData { 14 | dynamic balance; 15 | List? seconds; 16 | ProposalImageData? image; 17 | String? imageHash; 18 | String? proposer; 19 | dynamic index; 20 | } 21 | 22 | @JsonSerializable() 23 | class ProposalImageData extends _ProposalImageData { 24 | static ProposalImageData fromJson(Map json) => 25 | _$ProposalImageDataFromJson(json); 26 | Map toJson() => _$ProposalImageDataToJson(this); 27 | } 28 | 29 | abstract class _ProposalImageData { 30 | dynamic balance; 31 | dynamic at; 32 | String? proposer; 33 | CouncilProposalData? proposal; 34 | } 35 | -------------------------------------------------------------------------------- /lib/api/types/parachain/auctionData.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | import 'package:polkawallet_sdk/api/types/parachain/bidData.dart'; 3 | import 'package:polkawallet_sdk/api/types/parachain/fundData.dart'; 4 | 5 | part 'auctionData.g.dart'; 6 | 7 | @JsonSerializable(explicitToJson: true) 8 | class AuctionData extends _AuctionData { 9 | static AuctionData fromJson(Map json) => 10 | _$AuctionDataFromJson(json as Map); 11 | Map toJson() => _$AuctionDataToJson(this); 12 | } 13 | 14 | abstract class _AuctionData { 15 | AuctionOverview auction = AuctionOverview(); 16 | List funds = []; 17 | List winners = []; 18 | } 19 | 20 | @JsonSerializable() 21 | class AuctionOverview extends _AuctionOverview { 22 | static AuctionOverview fromJson(Map json) => 23 | _$AuctionOverviewFromJson(json as Map); 24 | Map toJson() => _$AuctionOverviewToJson(this); 25 | } 26 | 27 | abstract class _AuctionOverview { 28 | String? bestNumber; 29 | String? endBlock; 30 | int? numAuctions; 31 | int? leasePeriod; 32 | int? leaseEnd; 33 | } 34 | -------------------------------------------------------------------------------- /js_as_extension/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@polkawallet/extension", 3 | "description": "A Polkawallet signer for the @polkadot/api", 4 | "version": "0.2.0-beta.1", 5 | "author": "Shawn Yang ", 6 | "license": "Apache-2", 7 | "scripts": { 8 | "clean": "rm -rf dist/*", 9 | "build": "webpack --mode production", 10 | "build-dev": "webpack --mode development" 11 | }, 12 | "dependencies": { 13 | "@babel/runtime": "^7.14.5", 14 | "process": "^0.11.10", 15 | "@polkadot/extension-base": "^0.43.1", 16 | "@polkadot/extension-dapp": "^0.43.1", 17 | "@polkadot/extension-inject": "^0.43.1" 18 | }, 19 | "devDependencies": { 20 | "@babel/core": "^7.14.8", 21 | "@babel/plugin-transform-runtime": "^7.14.5", 22 | "@babel/preset-env": "^7.14.8", 23 | "@webpack-cli/info": "^0.2.0", 24 | "@webpack-cli/init": "^0.3.0", 25 | "babel-loader": "^8.0.6", 26 | "eslint": "^6.8.0", 27 | "eslint-config-prettier": "^6.9.0", 28 | "eslint-plugin-prettier": "^3.1.2", 29 | "prettier": "^1.19.1", 30 | "webpack": "^5.65.0", 31 | "webpack-cli": "^4.9.2" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/service/localServer.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'package:flutter/foundation.dart'; 3 | import 'package:flutter_inappwebview/flutter_inappwebview.dart'; 4 | 5 | ///Single instance 6 | class LocalServer { 7 | final InAppLocalhostServer? _localhostServer; 8 | Future startLocalServer() async { 9 | if (_localhostServer?.isRunning() == true) { 10 | HttpClient client = HttpClient(); 11 | HttpClientRequest? request; 12 | try { 13 | request = await client.getUrl(Uri.parse('http://localhost:8080/')); 14 | } catch (error) { 15 | debugPrint(error.toString()); 16 | } 17 | final response = await request?.close(); 18 | client.close(); 19 | if (response?.statusCode == 200) { 20 | return; 21 | } 22 | } 23 | await _localhostServer?.close(); 24 | await _localhostServer?.start(); 25 | } 26 | 27 | LocalServer._internal(this._localhostServer); 28 | factory LocalServer() => _instance; 29 | 30 | static late final LocalServer _instance = 31 | LocalServer._internal(InAppLocalhostServer()); 32 | 33 | static LocalServer getInstance() => _instance; 34 | } 35 | -------------------------------------------------------------------------------- /lib/api/types/parachain/fundData.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'fundData.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | FundData _$FundDataFromJson(Map json) => FundData() 10 | ..paraId = json['paraId'] as String 11 | ..cap = json['cap'] 12 | ..value = json['value'] 13 | ..end = json['end'] 14 | ..firstSlot = json['firstSlot'] as int 15 | ..lastSlot = json['lastSlot'] as int 16 | ..isWinner = json['isWinner'] as bool 17 | ..isCapped = json['isCapped'] as bool 18 | ..isEnded = json['isEnded'] as bool; 19 | 20 | Map _$FundDataToJson(FundData instance) => { 21 | 'paraId': instance.paraId, 22 | 'cap': instance.cap, 23 | 'value': instance.value, 24 | 'end': instance.end, 25 | 'firstSlot': instance.firstSlot, 26 | 'lastSlot': instance.lastSlot, 27 | 'isWinner': instance.isWinner, 28 | 'isCapped': instance.isCapped, 29 | 'isEnded': instance.isEnded, 30 | }; 31 | -------------------------------------------------------------------------------- /lib/storage/types/keyPairData.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'keyPairData.g.dart'; 4 | 5 | @JsonSerializable() 6 | class KeyPairData extends _KeyPairData { 7 | static KeyPairData fromJson(Map json) => 8 | _$KeyPairDataFromJson(json); 9 | Map toJson() => _$KeyPairDataToJson(this); 10 | } 11 | 12 | abstract class _KeyPairData { 13 | String? name; 14 | String? address; 15 | String? encoded; 16 | String? pubKey; 17 | 18 | Map? encoding = Map(); 19 | Map? meta = Map(); 20 | 21 | String? memo; 22 | bool? observation = false; 23 | 24 | /// address avatar in svg format 25 | String? icon; 26 | 27 | /// indexInfo 28 | Map? indexInfo; 29 | } 30 | 31 | @JsonSerializable() 32 | class SeedBackupData extends _SeedBackupData { 33 | static SeedBackupData fromJson(Map json) => 34 | _$SeedBackupDataFromJson(json); 35 | Map toJson() => _$SeedBackupDataToJson(this); 36 | } 37 | 38 | abstract class _SeedBackupData { 39 | String? type; 40 | String? seed; 41 | String? error; 42 | } 43 | -------------------------------------------------------------------------------- /lib/api/types/networkStateData.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'networkStateData.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | NetworkStateData _$NetworkStateDataFromJson(Map json) => 10 | NetworkStateData() 11 | ..ss58Format = json['ss58Format'] as int? 12 | ..tokenDecimals = (json['tokenDecimals'] as List?) 13 | ?.map((e) => e as int) 14 | .toList() 15 | ..tokenSymbol = (json['tokenSymbol'] as List?) 16 | ?.map((e) => e as String) 17 | .toList() 18 | ..name = json['name'] as String? 19 | ..genesisHash = json['genesisHash'] as String?; 20 | 21 | Map _$NetworkStateDataToJson(NetworkStateData instance) => 22 | { 23 | 'ss58Format': instance.ss58Format, 24 | 'tokenDecimals': instance.tokenDecimals, 25 | 'tokenSymbol': instance.tokenSymbol, 26 | 'name': instance.name, 27 | 'genesisHash': instance.genesisHash, 28 | }; 29 | -------------------------------------------------------------------------------- /lib/api/apiParachain.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:polkawallet_sdk/api/api.dart'; 4 | import 'package:polkawallet_sdk/api/types/parachain/auctionData.dart'; 5 | import 'package:polkawallet_sdk/api/types/parachain/parasOverviewData.dart'; 6 | import 'package:polkawallet_sdk/service/parachain.dart'; 7 | 8 | class ApiParachain { 9 | ApiParachain(this.apiRoot, this.service); 10 | 11 | final PolkawalletApi apiRoot; 12 | final ServiceParachain service; 13 | 14 | Future queryParasOverview() async { 15 | final res = await service.queryParasOverview(); 16 | return ParasOverviewData.fromJson(res ?? {}); 17 | } 18 | 19 | Future queryAuctionWithWinners() async { 20 | final res = await service.queryAuctionWithWinners(); 21 | return AuctionData.fromJson(res!); 22 | } 23 | 24 | Future> queryUserContributions( 25 | List paraIds, String pubKey) async { 26 | return service.queryUserContributions(paraIds, pubKey); 27 | } 28 | 29 | /// chainName: kusamaPeople supported. 30 | Future connectParachain(String chainName) async { 31 | return service.connectParachain(chainName); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/storage/types/ethWalletData.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'ethWalletData.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | EthWalletData _$EthWalletDataFromJson(Map json) => 10 | EthWalletData() 11 | ..address = json['address'] as String? 12 | ..name = json['name'] as String? 13 | ..id = json['id'] as String? 14 | ..version = json['version'] as int? 15 | ..crypto = json['crypto'] as Map? 16 | ..memo = json['memo'] as String? 17 | ..observation = json['observation'] as bool? 18 | ..icon = json['icon'] as String?; 19 | 20 | Map _$EthWalletDataToJson(EthWalletData instance) => 21 | { 22 | 'address': instance.address, 23 | 'name': instance.name, 24 | 'id': instance.id, 25 | 'version': instance.version, 26 | 'crypto': instance.crypto, 27 | 'memo': instance.memo, 28 | 'observation': instance.observation, 29 | 'icon': instance.icon, 30 | }; 31 | -------------------------------------------------------------------------------- /lib/service/parachain.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:polkawallet_sdk/service/index.dart'; 4 | 5 | class ServiceParachain { 6 | ServiceParachain(this.serviceRoot); 7 | 8 | final SubstrateService serviceRoot; 9 | 10 | Future queryParasOverview() async { 11 | final res = await serviceRoot.webView! 12 | .evalJavascript('parachain.queryParasOverview(api)') as Map?; 13 | return res; 14 | } 15 | 16 | Future queryAuctionWithWinners() async { 17 | final res = await serviceRoot.webView! 18 | .evalJavascript('parachain.queryAuctionWithWinners(api)') as Map?; 19 | return res; 20 | } 21 | 22 | Future> queryUserContributions( 23 | List paraIds, String pubKey) async { 24 | final res = await serviceRoot.webView!.evalJavascript('Promise.all([' 25 | '${paraIds.map((e) => 'parachain.queryUserContributions(api, "$e", "$pubKey")').join(',')}])'); 26 | return List.from(res); 27 | } 28 | 29 | Future connectParachain(String chainName) async { 30 | final res = await serviceRoot.webView! 31 | .evalJavascript('multiChain.connectParachain("$chainName")') as String?; 32 | return res; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | example/build/ 34 | 35 | # Web related 36 | lib/generated_plugin_registrant.dart 37 | 38 | # Symbolication related 39 | app.*.symbols 40 | 41 | # Obfuscation related 42 | app.*.map.json 43 | 44 | # Exceptions to above rules. 45 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 46 | 47 | js_api/node_modules/ 48 | js_api/.yarn/* 49 | !js_api/.yarn/patches 50 | !js_api/.yarn/plugins 51 | !js_api/.yarn/releases 52 | !js_api/.yarn/sdks 53 | !js_api/.yarn/versions 54 | 55 | js_api/dist/*.js.LICENSE.txt 56 | 57 | js_as_extension/node_modules/ 58 | js_api_eth/node_modules/ 59 | -------------------------------------------------------------------------------- /lib/storage/localStorage.dart: -------------------------------------------------------------------------------- 1 | import 'package:get_storage/get_storage.dart'; 2 | 3 | const String sdk_storage_key = 'polka_wallet_sdk'; 4 | const String sdk_evm_storage_key = 'polka_wallet_sdk_evm'; 5 | 6 | /// this is where we save keyPairs locally 7 | class KeyringStorage { 8 | static final _storage = () => GetStorage(sdk_storage_key); 9 | 10 | final keyPairs = [].val('keyPairs', getBox: _storage); 11 | final contacts = [].val('contacts', getBox: _storage); 12 | final ReadWriteValue currentPubKey = 13 | ''.val('currentPubKey', getBox: _storage); 14 | final encryptedRawSeeds = {}.val('encryptedRawSeeds', getBox: _storage); 15 | final encryptedMnemonics = {}.val('encryptedMnemonics', getBox: _storage); 16 | } 17 | 18 | class KeyringEVMStorage { 19 | static final _storage = () => GetStorage(sdk_evm_storage_key); 20 | 21 | final keyPairs = [].val('keyPairs', getBox: _storage); 22 | final contacts = [].val('contacts', getBox: _storage); 23 | final ReadWriteValue currentAddress = 24 | ''.val('currentAddress', getBox: _storage); 25 | final encryptedPrivateKeys = {}.val('encryptedPrivateKeys', getBox: _storage); 26 | final encryptedMnemonics = {}.val('encryptedMnemonics', getBox: _storage); 27 | } 28 | -------------------------------------------------------------------------------- /lib/api/types/addressIconData.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'addressIconData.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | AddressIconDataWithMnemonic _$AddressIconDataWithMnemonicFromJson( 10 | Map json) => 11 | AddressIconDataWithMnemonic() 12 | ..mnemonic = json['mnemonic'] as String? 13 | ..address = json['address'] as String? 14 | ..svg = json['svg'] as String?; 15 | 16 | Map _$AddressIconDataWithMnemonicToJson( 17 | AddressIconDataWithMnemonic instance) => 18 | { 19 | 'mnemonic': instance.mnemonic, 20 | 'address': instance.address, 21 | 'svg': instance.svg, 22 | }; 23 | 24 | AddressIconData _$AddressIconDataFromJson(Map json) => 25 | AddressIconData() 26 | ..address = json['address'] as String? 27 | ..svg = json['svg'] as String?; 28 | 29 | Map _$AddressIconDataToJson(AddressIconData instance) => 30 | { 31 | 'address': instance.address, 32 | 'svg': instance.svg, 33 | }; 34 | -------------------------------------------------------------------------------- /.pubignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | example/build/ 34 | 35 | # Web related 36 | lib/generated_plugin_registrant.dart 37 | 38 | # Symbolication related 39 | app.*.symbols 40 | 41 | # Obfuscation related 42 | app.*.map.json 43 | 44 | # Exceptions to above rules. 45 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 46 | 47 | js_api/node_modules/ 48 | js_api/.yarn/* 49 | !js_api/.yarn/patches 50 | !js_api/.yarn/plugins 51 | !js_api/.yarn/releases 52 | !js_api/.yarn/sdks 53 | !js_api/.yarn/versions 54 | 55 | js_api/dist/*.js.LICENSE.txt 56 | 57 | js_as_extension/node_modules/ 58 | js_api_eth/node_modules/ 59 | 60 | mobile-provider/ 61 | mobile-provider 62 | -------------------------------------------------------------------------------- /lib/service/uos.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:convert'; 3 | 4 | import 'package:polkawallet_sdk/service/index.dart'; 5 | 6 | /// Support offline-signature as a hot-wallet: 7 | /// 1. makeQrCode 8 | /// 2. addSignatureAndSend: send tx with address of step1 & signature of step2. 9 | class ServiceUOS { 10 | ServiceUOS(this.serviceRoot); 11 | 12 | final SubstrateService serviceRoot; 13 | 14 | Future addSignatureAndSend( 15 | String address, 16 | signed, 17 | Function(String) onStatusChange, 18 | ) async { 19 | final msgId = 20 | "onStatusChange${serviceRoot.webView!.getEvalJavascriptUID()}"; 21 | serviceRoot.webView!.addMsgHandler(msgId, onStatusChange); 22 | 23 | final dynamic res = await serviceRoot.webView!.evalJavascript( 24 | 'keyring.addSignatureAndSend(api, "$address", "$signed")'); 25 | serviceRoot.webView!.removeMsgHandler(msgId); 26 | 27 | return res; 28 | } 29 | 30 | Future makeQrCode(Map txInfo, List params, 31 | {String? rawParam, int? ss58}) async { 32 | String param = rawParam != null ? rawParam : jsonEncode(params); 33 | final dynamic res = await serviceRoot.webView!.evalJavascript( 34 | 'keyring.makeTx(api, ${jsonEncode(txInfo)}, $param, $ss58)', 35 | ); 36 | return res; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/api/apiUOS.dart: -------------------------------------------------------------------------------- 1 | import 'package:polkawallet_sdk/api/api.dart'; 2 | import 'package:polkawallet_sdk/api/types/txInfoData.dart'; 3 | import 'package:polkawallet_sdk/service/uos.dart'; 4 | 5 | /// Support offline-signature as a hot-wallet: 6 | /// 1. makeQrCode 7 | /// 2. addSignatureAndSend: send tx with address of step1 & signature of step2. 8 | class ApiUOS { 9 | ApiUOS(this.apiRoot, this.service); 10 | 11 | final PolkawalletApi apiRoot; 12 | final ServiceUOS service; 13 | 14 | /// [onStatusChange] is a callback when tx status change. 15 | /// @return txHash [string] if tx finalized success. 16 | Future addSignatureAndSend( 17 | String address, 18 | signed, 19 | Function(String) onStatusChange, 20 | ) async { 21 | final res = await service.addSignatureAndSend( 22 | address, 23 | signed, 24 | onStatusChange, 25 | ); 26 | if (res?['error'] != null) { 27 | throw Exception(res?['error']); 28 | } 29 | return res; 30 | } 31 | 32 | Future makeQrCode(TxInfoData txInfo, List params, 33 | {String? rawParam}) async { 34 | final Map? res = await service.makeQrCode( 35 | txInfo.toJson(), 36 | params, 37 | rawParam: rawParam, 38 | ss58: apiRoot.connectedNode!.ss58, 39 | ); 40 | return res; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/service/setting.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:polkawallet_sdk/service/index.dart'; 4 | 5 | class ServiceSetting { 6 | ServiceSetting(this.serviceRoot); 7 | 8 | final SubstrateService serviceRoot; 9 | 10 | Future queryNetwork() async { 11 | // fetch network info 12 | List res = await serviceRoot.webView!.evalJavascript( 13 | 'Promise.all([settings.getNetworkProperties(api),api.rpc.system.chain(),settings.getNetworkConst(api)])'); 14 | if (res[0] == null || res[1] == null || res[2] == null) { 15 | return null; 16 | } 17 | 18 | final Map props = {"props": res[0], "const": res[2]}; 19 | props["props"]['name'] = res[1]; 20 | return props; 21 | } 22 | 23 | Future queryNetworkConst() async { 24 | final dynamic res = await serviceRoot.webView! 25 | .evalJavascript('settings.getNetworkConst(api)'); 26 | return res; 27 | } 28 | 29 | Future queryNetworkProps() async { 30 | // fetch network info 31 | List res = await serviceRoot.webView!.evalJavascript( 32 | 'Promise.all([settings.getNetworkProperties(api), api.rpc.system.chain()])'); 33 | if (res[0] == null || res[1] == null) { 34 | return null; 35 | } 36 | 37 | final Map props = res[0]; 38 | props['name'] = res[1]; 39 | return props; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/api/apiSetting.dart: -------------------------------------------------------------------------------- 1 | import 'package:polkawallet_sdk/api/api.dart'; 2 | import 'package:polkawallet_sdk/api/types/networkStateData.dart'; 3 | import 'package:polkawallet_sdk/service/setting.dart'; 4 | 5 | class ApiSetting { 6 | ApiSetting(this.apiRoot, this.service); 7 | 8 | final PolkawalletApi apiRoot; 9 | final ServiceSetting? service; 10 | 11 | final _msgChannel = "BestNumber"; 12 | 13 | /// query network const. 14 | Future queryNetworkConst() async { 15 | final Map? res = await service!.queryNetworkConst(); 16 | return res; 17 | } 18 | 19 | /// query network properties. 20 | Future queryNetworkProps() async { 21 | final Map? res = await service!.queryNetworkProps(); 22 | if (res == null) { 23 | return null; 24 | } 25 | return NetworkStateData.fromJson(res as Map); 26 | } 27 | 28 | /// subscribe best number. 29 | /// @return [String] msgChannel, call unsubscribeMessage(msgChannel) to unsub. 30 | Future subscribeBestNumber(Function callback) async { 31 | apiRoot.subscribeMessage( 32 | 'api.derive.chain.bestNumber', 33 | [], 34 | _msgChannel, 35 | callback, 36 | ); 37 | } 38 | 39 | Future unsubscribeBestNumber() async { 40 | apiRoot.service.webView!.unsubscribeMessage(_msgChannel); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/service/gov2.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:convert'; 3 | 4 | import 'package:polkawallet_sdk/service/index.dart'; 5 | 6 | class ServiceGov2 { 7 | ServiceGov2(this.serviceRoot); 8 | 9 | final SubstrateService serviceRoot; 10 | 11 | Future checkGovExist(int version) async { 12 | final bool? res = await serviceRoot.webView!.evalJavascript( 13 | 'gov2.checkGovExist(api, $version)', 14 | wrapPromise: false); 15 | return res ?? false; 16 | } 17 | 18 | Future queryReferendums(String address) async { 19 | final Map res = await serviceRoot.webView! 20 | .evalJavascript('gov2.queryReferendums(api, "$address")'); 21 | return res; 22 | } 23 | 24 | Future getExternalLinks(Map params) async { 25 | final dynamic res = await serviceRoot.webView! 26 | .evalJavascript('settings.genLinks(api, ${jsonEncode(params)})'); 27 | return res; 28 | } 29 | 30 | Future getReferendumVoteConvictions() async { 31 | final dynamic res = await serviceRoot.webView! 32 | .evalJavascript('gov2.getReferendumVoteConvictions(api)'); 33 | return res; 34 | } 35 | 36 | Future queryReferendaLocks(String address) async { 37 | final dynamic data = await serviceRoot.webView! 38 | .evalJavascript('gov2.queryReferendaLocks(api, "$address")'); 39 | return data; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/service/tx.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:convert'; 3 | 4 | import 'package:polkawallet_sdk/service/index.dart'; 5 | 6 | class ServiceTx { 7 | ServiceTx(this.serviceRoot); 8 | 9 | final SubstrateService serviceRoot; 10 | 11 | Future estimateFees(Map txInfo, String params, {String? jsApi}) async { 12 | dynamic res = await serviceRoot.webView!.evalJavascript( 13 | 'keyring.txFeeEstimate(${jsApi ?? 'api'}, ${jsonEncode(txInfo)}, $params)', 14 | ); 15 | return res; 16 | } 17 | 18 | // Future _testSendTx() async { 19 | // Completer c = new Completer(); 20 | // void onComplete(res) { 21 | // c.complete(res); 22 | // } 23 | // 24 | // Timer(Duration(seconds: 6), () => onComplete({'hash': '0x79867'})); 25 | // return c.future; 26 | // } 27 | 28 | Future signAndSend(Map txInfo, String params, password, 29 | Function(String) onStatusChange) async { 30 | final msgId = 31 | "onStatusChange${serviceRoot.webView!.getEvalJavascriptUID()}"; 32 | serviceRoot.webView!.addMsgHandler(msgId, onStatusChange); 33 | final code = 34 | 'keyring.sendTx(api, ${jsonEncode(txInfo)}, $params, "$password", "$msgId")'; 35 | // print(code); 36 | final dynamic res = await serviceRoot.webView!.evalJavascript(code); 37 | serviceRoot.webView!.removeMsgHandler(msgId); 38 | 39 | return res; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /js_api/src/service/walletconnect/v2/data/PolkadotData.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Types 3 | */ 4 | export type TPolkadotChain = keyof typeof POLKADOT_MAINNET_CHAINS; 5 | 6 | /** 7 | * Chains: 8 | * Recording to https://github.com/ChainAgnostic/CAIPs/issues/13, 9 | * ChainId is the first 32 characters of the genesis hash. 10 | */ 11 | export const POLKADOT_MAINNET_CHAINS = { 12 | "polkadot:91b171bb158e2d3848fa23a9f1c25182": { 13 | chainId: "91b171bb158e2d3848fa23a9f1c25182", 14 | name: "Polkadot", 15 | }, 16 | "polkadot:b0a8d493285c2df73290dfb7e61f870f": { 17 | chainId: "b0a8d493285c2df73290dfb7e61f870f", 18 | name: "Kusama", 19 | }, 20 | "polkadot:68d56f15f85d3136970ec16946040bc1": { 21 | chainId: "68d56f15f85d3136970ec16946040bc1", 22 | name: "Statemint", 23 | }, 24 | "polkadot:48239ef607d7928874027a43a6768920": { 25 | chainId: "48239ef607d7928874027a43a6768920", 26 | name: "Statemine", 27 | }, 28 | "polkadot:fc41b9bd8ef8fe53d58c7ea67c794c7e": { 29 | chainId: "fc41b9bd8ef8fe53d58c7ea67c794c7e", 30 | name: "Acala", 31 | }, 32 | "polkadot:baf5aabe40646d11f0ee8abbdc64f4a4": { 33 | chainId: "baf5aabe40646d11f0ee8abbdc64f4a4", 34 | name: "Karura", 35 | }, 36 | }; 37 | 38 | /** 39 | * Methods 40 | */ 41 | export const POLKADOT_SIGNING_METHODS = { 42 | POLKADOT_SIGN_TRANSACTION: "polkadot_signTransaction", 43 | POLKADOT_SIGN_MESSAGE: "polkadot_signMessage", 44 | }; 45 | -------------------------------------------------------------------------------- /lib/api/types/txData.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'txData.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | TxData _$TxDataFromJson(Map json) => TxData() 10 | ..blockNum = json['block_num'] as int? 11 | ..blockTimestamp = json['block_timestamp'] as int? 12 | ..accountId = json['account_id'] as String? 13 | ..module = json['call_module'] as String? 14 | ..call = json['call_module_function'] as String? 15 | ..hash = json['extrinsic_hash'] as String? 16 | ..txNumber = json['extrinsic_index'] as String? 17 | ..fee = json['fee'] as String? 18 | ..params = json['params'] as String? 19 | ..nonce = json['nonce'] as int? 20 | ..success = json['success'] as bool?; 21 | 22 | Map _$TxDataToJson(TxData instance) => { 23 | 'block_num': instance.blockNum, 24 | 'block_timestamp': instance.blockTimestamp, 25 | 'account_id': instance.accountId, 26 | 'call_module': instance.module, 27 | 'call_module_function': instance.call, 28 | 'extrinsic_hash': instance.hash, 29 | 'extrinsic_index': instance.txNumber, 30 | 'fee': instance.fee, 31 | 'params': instance.params, 32 | 'nonce': instance.nonce, 33 | 'success': instance.success, 34 | }; 35 | -------------------------------------------------------------------------------- /lib/api/apiAssets.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:polkawallet_sdk/api/api.dart'; 4 | import 'package:polkawallet_sdk/api/types/balanceData.dart'; 5 | import 'package:polkawallet_sdk/plugin/store/balances.dart'; 6 | import 'package:polkawallet_sdk/service/assets.dart'; 7 | 8 | class ApiAssets { 9 | ApiAssets(this.apiRoot, this.service); 10 | 11 | final PolkawalletApi apiRoot; 12 | final ServiceAssets service; 13 | 14 | Future> getAssetsAll() async { 15 | final List? res = await (service.getAssetsAll()); 16 | if (res == null) { 17 | return []; 18 | } 19 | return res 20 | .map((e) => TokenBalanceData( 21 | id: e['id'].toString(), 22 | name: e['symbol'], 23 | fullName: e['name'], 24 | symbol: e['symbol'], 25 | decimals: int.parse(e['decimals']), 26 | )) 27 | .toList(); 28 | } 29 | 30 | Future> queryAssetsBalances( 31 | List ids, String address) async { 32 | final res = await service.queryAssetsBalances(ids, address); 33 | 34 | return res 35 | .asMap() 36 | .map((k, v) { 37 | final e = v ?? {}; 38 | e['id'] = ids[k]; 39 | return MapEntry(k, 40 | v != null ? AssetsBalanceData.fromJson(e) : AssetsBalanceData()); 41 | }) 42 | .values 43 | .toList(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /js_api/src/utils/config/links/polkassembly.ts: -------------------------------------------------------------------------------- 1 | export const PolkassemblyIo = { 2 | chains: { 3 | Altair: "Altair", 4 | Astar: "astar", 5 | "Bifrost Polkadot": "bifrost", 6 | Calamari: "calamari", 7 | "Centrifuge Mainnet": "centrifuge", 8 | Khala: "khala", 9 | Kusama: "kusama", 10 | "Kusama CC3": "kusama", 11 | Parallel: "parallel", 12 | "Parallel Heiko": "heiko", 13 | "Pioneer Network": "pioneer", 14 | Polkadex: "polkadex", 15 | Polkadot: "polkadot", 16 | Robonomics: "robonomics", 17 | Shibuya: "shibuya", 18 | Shiden: "shiden", 19 | }, 20 | create: (chain: string, path: string, data: any) => `https://${chain}.polkassembly.io/${path}/${data.toString()}`, 21 | isActive: true, 22 | paths: { 23 | council: "motion", 24 | proposal: "proposal", 25 | referendum: "referendum", 26 | treasury: "treasury", 27 | referenda: "referenda", 28 | }, 29 | url: "https://polkassembly.io/", 30 | }; 31 | 32 | export const PolkassemblyNetwork = { 33 | ...PolkassemblyIo, 34 | chains: { 35 | Bifrost: "bifrost", 36 | "KILT Spiritnet": "kilt", 37 | Karura: "karura", 38 | "Khala Network": "khala", 39 | "Moonbase Alpha": "moonbase", 40 | Moonbeam: "moonbeam", 41 | Moonriver: "moonriver", 42 | }, 43 | create: (chain: string, path: string, data: any): string => `https://${chain}.polkassembly.network/${path}/${data.toString()}`, 44 | url: "https://polkassembly.network/", 45 | }; 46 | -------------------------------------------------------------------------------- /js_api/src/service/walletconnect/engines/index.ts: -------------------------------------------------------------------------------- 1 | import { IRpcEngine } from "../v1/helpers/types"; 2 | import { IAppState } from "../v1/client"; 3 | import { IAppState2 } from "../v2/client"; 4 | import ethereum from "./ethereum"; 5 | import polkadot from "./polkadot"; 6 | 7 | class RpcEngine implements IRpcEngine { 8 | public engines: IRpcEngine[]; 9 | constructor(engines: IRpcEngine[]) { 10 | this.engines = engines; 11 | } 12 | 13 | public filter(payload: any) { 14 | const engine = this.getEngine(payload); 15 | return engine.filter(payload); 16 | } 17 | 18 | public router(payload: any, state: IAppState | IAppState2, setState: any) { 19 | const engine = this.getEngine(payload); 20 | return engine.router(payload, state, setState); 21 | } 22 | 23 | public render(payload: any) { 24 | const engine = this.getEngine(payload); 25 | return engine.render(payload); 26 | } 27 | 28 | public signer(payload: any, state: IAppState | IAppState2, pass: string, gasOptions: any) { 29 | const engine = this.getEngine(payload); 30 | return engine.signer(payload, state, pass, gasOptions); 31 | } 32 | 33 | private getEngine(payload: any) { 34 | const match = this.engines.filter((engine) => engine.filter(payload)); 35 | if (!match || !match.length) { 36 | throw new Error(`No RPC Engine found to handle payload with method ${payload.method}`); 37 | } 38 | return match[0]; 39 | } 40 | } 41 | 42 | export function getRpcEngine() { 43 | return new RpcEngine([ethereum, polkadot]); 44 | } 45 | -------------------------------------------------------------------------------- /js_api/src/service/walletconnect/v2/data/EIP155Data.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @desc Refference list of eip155 chains 3 | * @url https://chainlist.org 4 | */ 5 | 6 | /** 7 | * Types 8 | */ 9 | export type TEIP155Chain = keyof typeof EIP155_CHAINS; 10 | 11 | /** 12 | * Chains 13 | */ 14 | export const EIP155_MAINNET_CHAINS = { 15 | "eip155:1": { 16 | chainId: 1, 17 | name: "Ethereum", 18 | rpc: "https://cloudflare-eth.com/", 19 | }, 20 | }; 21 | 22 | export const EIP155_TEST_CHAINS = { 23 | "eip155:5": { 24 | chainId: 5, 25 | name: "Ethereum Goerli", 26 | rpc: "https://goerli.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161", 27 | }, 28 | "eip155:596": { 29 | chainId: 596, 30 | name: "Karura Testnet", 31 | rpc: "https://eth-rpc-karura-testnet.aca-staging.network/eth/http", 32 | }, 33 | "eip155:597": { 34 | chainId: 597, 35 | name: "Acala Testnet", 36 | rpc: "https://eth-rpc-acala-testnet.aca-staging.network/eth/http", 37 | }, 38 | }; 39 | 40 | export const EIP155_CHAINS = { ...EIP155_MAINNET_CHAINS, ...EIP155_TEST_CHAINS }; 41 | 42 | /** 43 | * Methods 44 | */ 45 | export const EIP155_SIGNING_METHODS = { 46 | PERSONAL_SIGN: "personal_sign", 47 | ETH_SIGN: "eth_sign", 48 | ETH_SIGN_TRANSACTION: "eth_signTransaction", 49 | ETH_SIGN_TYPED_DATA: "eth_signTypedData", 50 | ETH_SIGN_TYPED_DATA_V3: "eth_signTypedData_v3", 51 | ETH_SIGN_TYPED_DATA_V4: "eth_signTypedData_v4", 52 | ETH_SEND_RAW_TRANSACTION: "eth_sendRawTransaction", 53 | ETH_SEND_TRANSACTION: "eth_sendTransaction", 54 | }; 55 | -------------------------------------------------------------------------------- /lib/api/apiGov2.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:polkawallet_sdk/api/api.dart'; 4 | import 'package:polkawallet_sdk/api/types/gov/genExternalLinksParams.dart'; 5 | import 'package:polkawallet_sdk/api/types/gov/referendumV2Data.dart'; 6 | import 'package:polkawallet_sdk/service/gov2.dart'; 7 | 8 | class ApiGov2 { 9 | ApiGov2(this.apiRoot, this.service); 10 | 11 | final PolkawalletApi apiRoot; 12 | final ServiceGov2 service; 13 | 14 | Future checkGovExist(int version) async { 15 | return service.checkGovExist(version); 16 | } 17 | 18 | Future queryReferendums(String address) async { 19 | final Map res = await service.queryReferendums(address); 20 | final ongoing = List.from( 21 | res['ongoing'].map((e) => ReferendumGroup.fromJson(e))); 22 | final userVotes = List.from( 23 | res['userVotes'].map((e) => ReferendumVote.fromJson(e))); 24 | return ReferendumData(ongoing: ongoing, userVotes: userVotes); 25 | } 26 | 27 | Future getExternalLinks(GenExternalLinksParams params) async { 28 | final List? res = await service.getExternalLinks(params.toJson()); 29 | return res; 30 | } 31 | 32 | Future getReferendumVoteConvictions() async { 33 | final List? res = await service.getReferendumVoteConvictions(); 34 | return res; 35 | } 36 | 37 | Future queryReferendaLocks(String address) async { 38 | final List? res = await service.queryReferendaLocks(address); 39 | return res; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/api/types/evmTxData.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'evmTxData.g.dart'; 4 | 5 | @JsonSerializable() 6 | class EvmTxData { 7 | final String? value; 8 | final String? blockHash; 9 | final String? blockNumber; 10 | final String? confirmations; 11 | final String? contractAddress; 12 | final String? cumulativeGasUsed; 13 | final String? from; 14 | final String? gas; 15 | final String? gasPrice; 16 | final String? gasUsed; 17 | final String? hash; 18 | final String? input; 19 | final String? logIndex; 20 | final String? nonce; 21 | final String? timeStamp; 22 | final String? to; 23 | String? tokenDecimal; 24 | String? tokenName; 25 | String? tokenSymbol; 26 | final String? transactionIndex; 27 | final String? isError; 28 | 29 | EvmTxData( 30 | {this.value, 31 | this.blockHash, 32 | this.blockNumber, 33 | this.confirmations, 34 | this.contractAddress, 35 | this.cumulativeGasUsed, 36 | this.from, 37 | this.gas, 38 | this.gasPrice, 39 | this.gasUsed, 40 | this.hash, 41 | this.input, 42 | this.logIndex, 43 | this.nonce, 44 | this.timeStamp, 45 | this.to, 46 | this.tokenDecimal, 47 | this.tokenName, 48 | this.tokenSymbol, 49 | this.transactionIndex, 50 | this.isError}); 51 | 52 | factory EvmTxData.fromJson(Map json) => 53 | _$EvmTxDataFromJson(json); 54 | 55 | Map toJson() => _$EvmTxDataToJson(this); 56 | } 57 | -------------------------------------------------------------------------------- /js_api/src/service/staking/inflation.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2017-2021 @polkadot/app-config authors & contributors 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | import type { ApiPromise } from '@polkadot/api'; 5 | 6 | import { KUSAMA_GENESIS, POLKADOT_GENESIS } from '../../constants/networkSpect'; 7 | 8 | export interface Inflation { 9 | idealStake: number; 10 | idealInterest: number; 11 | inflation: number; 12 | stakedFraction: number; 13 | stakedReturn: number; 14 | } 15 | 16 | interface InflationParams { 17 | auctionAdjust: number; 18 | auctionMax: number; 19 | falloff: number; 20 | maxInflation: number; 21 | minInflation: number; 22 | stakeTarget: number; 23 | } 24 | 25 | const DEFAULT_PARAMS: InflationParams = { 26 | auctionAdjust: 0, 27 | auctionMax: 0, 28 | // 5% for falloff, as per the defaults, see 29 | // https://github.com/paritytech/polkadot/blob/816cb64ea16102c6c79f6be2a917d832d98df757/runtime/kusama/src/lib.rs#L534 30 | falloff: 0.05, 31 | // 10% max, 0.25% min, see 32 | // https://github.com/paritytech/polkadot/blob/816cb64ea16102c6c79f6be2a917d832d98df757/runtime/kusama/src/lib.rs#L523 33 | maxInflation: 0.1, 34 | minInflation: 0.025, 35 | stakeTarget: 0.5 36 | }; 37 | 38 | const KNOWN_PARAMS: Record = { 39 | [KUSAMA_GENESIS]: { ...DEFAULT_PARAMS, stakeTarget: 0.75 }, 40 | [POLKADOT_GENESIS]: { ...DEFAULT_PARAMS, stakeTarget: 0.75 } 41 | }; 42 | 43 | export function getInflationParams (api: ApiPromise): InflationParams { 44 | return KNOWN_PARAMS[api.genesisHash.toHex()] || DEFAULT_PARAMS; 45 | } 46 | -------------------------------------------------------------------------------- /test/polkawallet_sdk_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | 3 | import 'package:polkawallet_sdk/polkawallet_sdk.dart'; 4 | // import 'package:polkawallet_sdk/service/account.dart'; 5 | // import 'package:polkawallet_sdk/service/index.dart'; 6 | // import 'package:polkawallet_sdk/storage/keyring.dart'; 7 | // import 'package:polkawallet_sdk/storage/types/keyPairData.dart'; 8 | 9 | void main() { 10 | // const testKeystore = 11 | // '{"pubKey":"0xcc597bd2e7eda5094d6aa462523b629a502db6cc71a6ae0e9b158d9e42c6c462","mnemonic":"welcome clinic duck mom connect heart poet admit vendor robot group vacuum","rawSeed":"","address":"15cwMLiH57HvrqBfMYpt5AgGrb5SAUKx7XQUcHnBSs2DAsGt","encoded":"taoH2SolrO8UhraK1JxuNW9AcMMPY5UXMTJjlcpuyEEAgAAAAQAAAAgAAADdvrSwzB9yIFQ7ZCHQoQQV93zLhlAiZlits1CX2hFNm3/zPjYW63U7NzoF76UU4hUvyUTmrvT/K37v0zQ1eFrXwXvc2fmKFJ17qSR2oDvHfuCb+ruCsSrx/UsGtNLbzyCiomVYGMvRh/EzHEfBQO4jGaDi4Sq5++8QE2vuDUTePF8WsVSb5L9N30SFuNQ1YiTH7XBRG9zQhQTofLl0","encoding":{"content":["pkcs8","sr25519"],"type":["scrypt","xsalsa20-poly1305"],"version":"3"},"meta":{}}'; 12 | 13 | group('sdk test', () { 14 | test('init sdk', () async { 15 | final sdk = WalletSDK(); 16 | expect(sdk.api, null); 17 | }); 18 | 19 | // test('account test', () async { 20 | // KeyPairData kdydata = KeyPairData.fromJson(jsonDecode(testKeystore)); 21 | // final account = ServiceAccount(SubstrateService()); 22 | // var decoded = await account.decodeAddress([kdydata.address]); 23 | // expect(decoded![kdydata.pubKey], kdydata.address); 24 | // }); 25 | }); 26 | } 27 | -------------------------------------------------------------------------------- /lib/api/types/gov/councilInfoData.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'councilInfoData.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | CouncilInfoData _$CouncilInfoDataFromJson(Map json) => 10 | CouncilInfoData() 11 | ..desiredSeats = json['desiredSeats'] as String? 12 | ..termDuration = json['termDuration'] as String? 13 | ..votingBond = json['votingBond'] as String? 14 | ..members = (json['members'] as List?) 15 | ?.map((e) => e as List) 16 | .toList() 17 | ..runnersUp = (json['runnersUp'] as List?) 18 | ?.map((e) => e as List) 19 | .toList() 20 | ..candidates = (json['candidates'] as List?) 21 | ?.map((e) => e as String) 22 | .toList() 23 | ..candidateCount = json['candidateCount'] as String? 24 | ..candidacyBond = json['candidacyBond'] as String?; 25 | 26 | Map _$CouncilInfoDataToJson(CouncilInfoData instance) => 27 | { 28 | 'desiredSeats': instance.desiredSeats, 29 | 'termDuration': instance.termDuration, 30 | 'votingBond': instance.votingBond, 31 | 'members': instance.members, 32 | 'runnersUp': instance.runnersUp, 33 | 'candidates': instance.candidates, 34 | 'candidateCount': instance.candidateCount, 35 | 'candidacyBond': instance.candidacyBond, 36 | }; 37 | -------------------------------------------------------------------------------- /lib/api/types/bridge/bridgeChainData.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'bridgeChainData.g.dart'; 4 | 5 | @JsonSerializable() 6 | class BridgeChainData { 7 | String id; 8 | String display; 9 | String icon; 10 | int paraChainId; 11 | int ss58Prefix; 12 | BridgeChainData({ 13 | required this.id, 14 | required this.display, 15 | required this.icon, 16 | required this.paraChainId, 17 | required this.ss58Prefix, 18 | }); 19 | 20 | static BridgeChainData fromJson(Map json) => 21 | _$BridgeChainDataFromJson(json); 22 | Map toJson() => _$BridgeChainDataToJson(this); 23 | } 24 | 25 | @JsonSerializable() 26 | class BridgeRouteData { 27 | String from; 28 | String to; 29 | String token; 30 | BridgeRouteData({ 31 | required this.from, 32 | required this.to, 33 | required this.token, 34 | }); 35 | 36 | static BridgeRouteData fromJson(Map json) => 37 | _$BridgeRouteDataFromJson(json); 38 | Map toJson() => _$BridgeRouteDataToJson(this); 39 | } 40 | 41 | @JsonSerializable() 42 | class BridgeNetworkProperties { 43 | int ss58Format; 44 | List tokenDecimals; 45 | List tokenSymbol; 46 | BridgeNetworkProperties({ 47 | required this.ss58Format, 48 | required this.tokenDecimals, 49 | required this.tokenSymbol, 50 | }); 51 | 52 | static BridgeNetworkProperties fromJson(Map json) => 53 | _$BridgeNetworkPropertiesFromJson(json); 54 | Map toJson() => _$BridgeNetworkPropertiesToJson(this); 55 | } 56 | -------------------------------------------------------------------------------- /lib/api/types/gov/treasuryTipData.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'treasuryTipData.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | TreasuryTipData _$TreasuryTipDataFromJson(Map json) => 10 | TreasuryTipData() 11 | ..hash = json['hash'] as String? 12 | ..reason = json['reason'] as String? 13 | ..who = json['who'] as String? 14 | ..closes = json['closes'] 15 | ..finder = json['finder'] as String? 16 | ..deposit = json['deposit'] 17 | ..tips = (json['tips'] as List?) 18 | ?.map((e) => TreasuryTipItemData.fromJson(e as Map)) 19 | .toList(); 20 | 21 | Map _$TreasuryTipDataToJson(TreasuryTipData instance) => 22 | { 23 | 'hash': instance.hash, 24 | 'reason': instance.reason, 25 | 'who': instance.who, 26 | 'closes': instance.closes, 27 | 'finder': instance.finder, 28 | 'deposit': instance.deposit, 29 | 'tips': instance.tips, 30 | }; 31 | 32 | TreasuryTipItemData _$TreasuryTipItemDataFromJson(Map json) => 33 | TreasuryTipItemData() 34 | ..address = json['address'] as String? 35 | ..value = json['value']; 36 | 37 | Map _$TreasuryTipItemDataToJson( 38 | TreasuryTipItemData instance) => 39 | { 40 | 'address': instance.address, 41 | 'value': instance.value, 42 | }; 43 | -------------------------------------------------------------------------------- /js_api/src/service/eth/account.ts: -------------------------------------------------------------------------------- 1 | import Jazzicon from "@metamask/jazzicon"; 2 | import { erc20Abi, getWeb3 } from "./settings"; 3 | /** 4 | * Get svg icons of addresses. 5 | */ 6 | async function genIcons(addresses: string[]) { 7 | return addresses.map((address) => { 8 | const icon = Jazzicon(16, parseInt(address.slice(2, 10), 16)); 9 | return [address, icon.innerHTML.replace(">", `>`)]; 10 | }); 11 | } 12 | 13 | async function getEthBalance(address: string) { 14 | return getWeb3().eth.getBalance(address); 15 | } 16 | 17 | async function getTokenBalance(address: string, contractAddresses: string[]) { 18 | return Promise.all( 19 | contractAddresses.map(async (token) => { 20 | const web3 = getWeb3().eth; 21 | const contract = new web3.Contract(erc20Abi, token); 22 | const [symbol, name, decimals, balance] = await Promise.all([ 23 | contract.methods.symbol().call(), 24 | contract.methods.name().call(), 25 | contract.methods.decimals().call(), 26 | contract.methods.balanceOf(address).call(), 27 | ]); 28 | return { 29 | contractAddress: token, 30 | symbol, 31 | name, 32 | decimals, 33 | amount: balance.toString(), 34 | }; 35 | }) 36 | ); 37 | } 38 | 39 | /** 40 | * validate input address & return checksumed. 41 | */ 42 | async function getAddress(address: string) { 43 | return getWeb3().utils.toChecksumAddress(address); 44 | } 45 | 46 | export default { 47 | genIcons, 48 | getEthBalance, 49 | getTokenBalance, 50 | getAddress, 51 | }; 52 | -------------------------------------------------------------------------------- /lib/api/apiRecovery.dart: -------------------------------------------------------------------------------- 1 | import 'package:polkawallet_sdk/api/api.dart'; 2 | import 'package:polkawallet_sdk/api/types/recoveryInfo.dart'; 3 | import 'package:polkawallet_sdk/service/recovery.dart'; 4 | 5 | class ApiRecovery { 6 | ApiRecovery(this.apiRoot, this.service); 7 | 8 | final PolkawalletApi apiRoot; 9 | final ServiceRecovery service; 10 | 11 | Future queryRecoverable(String address) async { 12 | // address = "J4sW13h2HNerfxTzPGpLT66B3HVvuU32S6upxwSeFJQnAzg"; 13 | final res = await service.queryRecoverable(address); 14 | if (res != null) { 15 | return RecoveryInfo.fromJson( 16 | Map.of(res as Map)); 17 | } 18 | return null; 19 | } 20 | 21 | Future> queryRecoverableList( 22 | List addresses) async { 23 | final List res = await service.queryRecoverableList(addresses); 24 | return res 25 | .map((e) => RecoveryInfo.fromJson(Map.of(e ?? {}))) 26 | .toList(); 27 | } 28 | 29 | Future queryActiveRecoveryAttempts( 30 | String address, List addressNew) async { 31 | final res = await service.queryActiveRecoveryAttempts(address, addressNew); 32 | return res; 33 | } 34 | 35 | Future queryActiveRecoveries( 36 | List addresses, String addressNew) async { 37 | final res = await service.queryActiveRecoveries(addresses, addressNew); 38 | return res; 39 | } 40 | 41 | Future queryRecoveryProxies(List addresses) async { 42 | final res = await service.queryRecoveryProxies(addresses); 43 | return res; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | platform :ios, '11.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | target.build_configurations.each do |config| 41 | config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = ‘9.0’ 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /.github/workflows/dart.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | 6 | name: Dart 7 | 8 | on: 9 | push: 10 | branches: [ "master" ] 11 | pull_request: 12 | branches: [ "master" ] 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v3 20 | 21 | # Note: This workflow uses the latest stable version of the Dart SDK. 22 | # You can specify other versions if desired, see documentation here: 23 | # https://github.com/dart-lang/setup-dart/blob/main/README.md 24 | - uses: dart-lang/setup-dart@v1 25 | with: 26 | sdk: 2.19.4 27 | 28 | - name: Install dependencies 29 | run: dart pub get 30 | 31 | # Uncomment this step to verify the use of 'dart format' on each commit. 32 | # - name: Verify formatting 33 | # run: dart format --output=none --set-exit-if-changed . 34 | 35 | # Consider passing '--fatal-infos' for slightly stricter analysis. 36 | - name: Analyze project source 37 | run: dart analyze 38 | 39 | # Your project will need to have tests in test/ and a dependency on 40 | # package:test for this step to succeed. Note that Flutter projects will 41 | # want to change this to 'flutter test'. 42 | # - name: Run tests 43 | # run: dart test 44 | 45 | - name: Publish to pub.dev 46 | env: 47 | PUB_PUBLISH_ACCESS_TOKEN: ${{ secrets.PUB_PUBLISH_ACCESS_TOKEN }} 48 | run: dart pub publish 49 | -------------------------------------------------------------------------------- /js_api/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const webpack = require("webpack"); 3 | 4 | const config = { 5 | entry: { 6 | index: "./src/index.ts", 7 | bridge: "./src/bridge.ts", 8 | }, 9 | output: { 10 | publicPath: path.resolve(__dirname, ""), 11 | path: path.resolve(__dirname, "dist"), 12 | filename: "[name].js", 13 | }, 14 | resolve: { 15 | extensions: [".ts", ".js", ".mjs", ".cjs", ".json"], 16 | fallback: { 17 | crypto: require.resolve("crypto-browserify"), 18 | stream: require.resolve("stream-browserify"), 19 | assert: require.resolve("assert"), 20 | buffer: require.resolve("buffer"), 21 | }, 22 | }, 23 | plugins: [ 24 | new webpack.ProvidePlugin({ 25 | process: "process/browser.js", 26 | Buffer: ["buffer", "Buffer"], 27 | }), 28 | ], 29 | module: { 30 | rules: [ 31 | { 32 | test: /\.ts$/, 33 | use: "babel-loader", 34 | exclude: /node_modules/, 35 | }, 36 | { 37 | test: /\.js$/, 38 | include: path.resolve(__dirname, "node_modules/@polkadot/"), 39 | use: "babel-loader", 40 | }, 41 | { 42 | test: /\.js$/, 43 | include: path.resolve(__dirname, "node_modules/@acala-network/"), 44 | use: "babel-loader", 45 | }, 46 | { 47 | test: /\.js$/, 48 | include: path.resolve(__dirname, "node_modules/@nuts-finance/"), 49 | use: "babel-loader", 50 | }, 51 | { 52 | test: /\.js$/, 53 | include: path.resolve(__dirname, "node_modules/@polkawallet/"), 54 | use: "babel-loader", 55 | }, 56 | ], 57 | }, 58 | }; 59 | 60 | module.exports = config; 61 | -------------------------------------------------------------------------------- /lib/service/eth/accountEth.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:http/http.dart'; 4 | import 'package:polkawallet_sdk/service/index.dart'; 5 | 6 | class ServiceAccountEth { 7 | ServiceAccountEth(this.serviceRoot); 8 | 9 | final SubstrateService serviceRoot; 10 | 11 | /// Get icons of addresses 12 | /// return svg strings 13 | Future getAddressIcons(List addresses) async { 14 | final dynamic res = await serviceRoot.webView! 15 | .evalJavascript('eth.account.genIcons(${jsonEncode(addresses)})'); 16 | return res; 17 | } 18 | 19 | Future getNativeTokenBalance(String address) async { 20 | final String? res = await serviceRoot.webView! 21 | .evalJavascript('eth.account.getEthBalance("$address")'); 22 | return res ?? '0'; 23 | } 24 | 25 | Future getTokenBalance( 26 | String address, List contractAddresses) async { 27 | final List? res = await serviceRoot.webView!.evalJavascript( 28 | 'eth.account.getTokenBalance("$address", ${jsonEncode(contractAddresses)})'); 29 | return res; 30 | } 31 | 32 | /// Validate address 33 | /// return checksumed address or null 34 | Future getAddress(String address) async { 35 | final String? res = await serviceRoot.webView! 36 | .evalJavascript('eth.account.getAddress("$address")'); 37 | return res; 38 | } 39 | 40 | Future queryEthGasParams() async { 41 | const url = 42 | 'https://gas-api.metaswap.codefi.network/networks/1/suggestedGasFees'; 43 | final res = await get(Uri.parse(url)); 44 | return jsonDecode(res.body); 45 | } 46 | } 47 | 48 | const postHeaders = {"Content-type": "application/json", "Accept": "*/*"}; 49 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /lib/api/types/parachain/auctionData.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'auctionData.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | AuctionData _$AuctionDataFromJson(Map json) => AuctionData() 10 | ..auction = AuctionOverview.fromJson(json['auction'] as Map) 11 | ..funds = (json['funds'] as List) 12 | .map((e) => FundData.fromJson(e as Map)) 13 | .toList() 14 | ..winners = (json['winners'] as List) 15 | .map((e) => BidData.fromJson(e as Map)) 16 | .toList(); 17 | 18 | Map _$AuctionDataToJson(AuctionData instance) => 19 | { 20 | 'auction': instance.auction.toJson(), 21 | 'funds': instance.funds.map((e) => e.toJson()).toList(), 22 | 'winners': instance.winners.map((e) => e.toJson()).toList(), 23 | }; 24 | 25 | AuctionOverview _$AuctionOverviewFromJson(Map json) => 26 | AuctionOverview() 27 | ..bestNumber = json['bestNumber'] as String? 28 | ..endBlock = json['endBlock'] as String? 29 | ..numAuctions = json['numAuctions'] as int? 30 | ..leasePeriod = json['leasePeriod'] as int? 31 | ..leaseEnd = json['leaseEnd'] as int?; 32 | 33 | Map _$AuctionOverviewToJson(AuctionOverview instance) => 34 | { 35 | 'bestNumber': instance.bestNumber, 36 | 'endBlock': instance.endBlock, 37 | 'numAuctions': instance.numAuctions, 38 | 'leasePeriod': instance.leasePeriod, 39 | 'leaseEnd': instance.leaseEnd, 40 | }; 41 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 8 | 11 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /lib/storage/types/keyPairData.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'keyPairData.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | KeyPairData _$KeyPairDataFromJson(Map json) => KeyPairData() 10 | ..name = json['name'] as String? 11 | ..address = json['address'] as String? 12 | ..encoded = json['encoded'] as String? 13 | ..pubKey = json['pubKey'] as String? 14 | ..encoding = json['encoding'] as Map? 15 | ..meta = json['meta'] as Map? 16 | ..memo = json['memo'] as String? 17 | ..observation = json['observation'] as bool? 18 | ..icon = json['icon'] as String? 19 | ..indexInfo = json['indexInfo'] as Map?; 20 | 21 | Map _$KeyPairDataToJson(KeyPairData instance) => 22 | { 23 | 'name': instance.name, 24 | 'address': instance.address, 25 | 'encoded': instance.encoded, 26 | 'pubKey': instance.pubKey, 27 | 'encoding': instance.encoding, 28 | 'meta': instance.meta, 29 | 'memo': instance.memo, 30 | 'observation': instance.observation, 31 | 'icon': instance.icon, 32 | 'indexInfo': instance.indexInfo, 33 | }; 34 | 35 | SeedBackupData _$SeedBackupDataFromJson(Map json) => 36 | SeedBackupData() 37 | ..type = json['type'] as String? 38 | ..seed = json['seed'] as String? 39 | ..error = json['error'] as String?; 40 | 41 | Map _$SeedBackupDataToJson(SeedBackupData instance) => 42 | { 43 | 'type': instance.type, 44 | 'seed': instance.seed, 45 | 'error': instance.error, 46 | }; 47 | -------------------------------------------------------------------------------- /lib/api/types/txInfoData.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'txInfoData.g.dart'; 4 | 5 | /// call api.tx[module][call](...params) with polkadot-js/api 6 | /// see https://polkadot.js.org/api/substrate/extrinsics.html 7 | /// for all available calls and params. 8 | @JsonSerializable(explicitToJson: true) 9 | class TxInfoData { 10 | TxInfoData( 11 | this.module, 12 | this.call, 13 | this.sender, { 14 | this.tip = '0', 15 | this.isUnsigned = false, 16 | this.proxy, 17 | this.txName, 18 | this.txHex, 19 | }); 20 | 21 | String? module; 22 | String? call; 23 | TxSenderData? sender; 24 | String? tip; 25 | String? txHex; 26 | 27 | bool? isUnsigned; 28 | 29 | /// proxy for calling recovery.asRecovered 30 | TxSenderData? proxy; 31 | 32 | /// txName for calling treasury.approveProposal & treasury.rejectProposal 33 | String? txName; 34 | 35 | static TxInfoData fromJson(Map json) => 36 | _$TxInfoDataFromJson(json); 37 | Map toJson() => _$TxInfoDataToJson(this); 38 | } 39 | 40 | @JsonSerializable() 41 | class TxSenderData { 42 | TxSenderData(this.address, this.pubKey); 43 | 44 | final String? address; 45 | final String? pubKey; 46 | 47 | static TxSenderData fromJson(Map json) => 48 | _$TxSenderDataFromJson(json); 49 | Map toJson() => _$TxSenderDataToJson(this); 50 | } 51 | 52 | @JsonSerializable() 53 | class TxFeeEstimateResult extends _TxFeeEstimateResult { 54 | static TxFeeEstimateResult fromJson(Map json) => 55 | _$TxFeeEstimateResultFromJson(json); 56 | Map toJson() => _$TxFeeEstimateResultToJson(this); 57 | } 58 | 59 | abstract class _TxFeeEstimateResult { 60 | dynamic weight; 61 | dynamic partialFee; 62 | } 63 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | CADisableMinimumFrameDurationOnPhone 45 | 46 | UIApplicationSupportsIndirectInputEvents 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /lib/api/types/gov/proposalInfoData.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'proposalInfoData.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ProposalInfoData _$ProposalInfoDataFromJson(Map json) => 10 | ProposalInfoData() 11 | ..balance = json['balance'] 12 | ..seconds = 13 | (json['seconds'] as List?)?.map((e) => e as String).toList() 14 | ..image = json['image'] == null 15 | ? null 16 | : ProposalImageData.fromJson(json['image'] as Map) 17 | ..imageHash = json['imageHash'] as String? 18 | ..proposer = json['proposer'] as String? 19 | ..index = json['index']; 20 | 21 | Map _$ProposalInfoDataToJson(ProposalInfoData instance) => 22 | { 23 | 'balance': instance.balance, 24 | 'seconds': instance.seconds, 25 | 'image': instance.image, 26 | 'imageHash': instance.imageHash, 27 | 'proposer': instance.proposer, 28 | 'index': instance.index, 29 | }; 30 | 31 | ProposalImageData _$ProposalImageDataFromJson(Map json) => 32 | ProposalImageData() 33 | ..balance = json['balance'] 34 | ..at = json['at'] 35 | ..proposer = json['proposer'] as String? 36 | ..proposal = json['proposal'] == null 37 | ? null 38 | : CouncilProposalData.fromJson( 39 | json['proposal'] as Map); 40 | 41 | Map _$ProposalImageDataToJson(ProposalImageData instance) => 42 | { 43 | 'balance': instance.balance, 44 | 'at': instance.at, 45 | 'proposer': instance.proposer, 46 | 'proposal': instance.proposal, 47 | }; 48 | -------------------------------------------------------------------------------- /lib/api/types/balanceData.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'balanceData.g.dart'; 4 | 5 | @JsonSerializable(explicitToJson: true) 6 | class BalanceData extends _BalanceData { 7 | static BalanceData fromJson(Map json) => 8 | _$BalanceDataFromJson(json); 9 | Map toJson() => _$BalanceDataToJson(this); 10 | } 11 | 12 | abstract class _BalanceData { 13 | String? accountId; 14 | dynamic accountNonce; 15 | dynamic availableBalance; 16 | dynamic freeBalance; 17 | dynamic frozenFee; 18 | dynamic frozenMisc; 19 | bool? isVesting; 20 | dynamic lockedBalance; 21 | List? lockedBreakdown; 22 | dynamic reservedBalance; 23 | dynamic vestedBalance; 24 | dynamic vestedClaimable; 25 | dynamic vestingEndBlock; 26 | dynamic vestingLocked; 27 | dynamic vestingPerBlock; 28 | dynamic vestingTotal; 29 | dynamic votingBalance; 30 | 31 | // use this to identify cache data 32 | bool? isFromCache; 33 | } 34 | 35 | @JsonSerializable() 36 | class BalanceBreakdownData extends _BalanceBreakdownData { 37 | static BalanceBreakdownData fromJson(Map json) => 38 | _$BalanceBreakdownDataFromJson(json); 39 | Map toJson() => _$BalanceBreakdownDataToJson(this); 40 | } 41 | 42 | abstract class _BalanceBreakdownData { 43 | String? id; 44 | dynamic amount; 45 | String? reasons; 46 | String? use; 47 | } 48 | 49 | class AssetsBalanceData extends _AssetsBalanceData { 50 | static AssetsBalanceData fromJson(Map json) { 51 | final data = AssetsBalanceData(); 52 | data.id = json['id']; 53 | data.balance = json['balance'].toString(); 54 | data.isFrozen = json['isFrozen']; 55 | data.isSufficient = json['isSufficient']; 56 | return data; 57 | } 58 | } 59 | 60 | abstract class _AssetsBalanceData { 61 | String? id; 62 | String? balance; 63 | bool? isFrozen; 64 | bool? isSufficient; 65 | } 66 | -------------------------------------------------------------------------------- /lib/api/apiTx.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:convert'; 3 | 4 | import 'package:polkawallet_sdk/api/api.dart'; 5 | import 'package:polkawallet_sdk/api/types/txInfoData.dart'; 6 | import 'package:polkawallet_sdk/service/tx.dart'; 7 | 8 | class ApiTx { 9 | ApiTx(this.apiRoot, this.service); 10 | 11 | final PolkawalletApi apiRoot; 12 | final ServiceTx service; 13 | 14 | /// Estimate tx fees, [params] will be ignored if we have [rawParam]. 15 | Future estimateFees(TxInfoData txInfo, List params, 16 | {String? rawParam, String? jsApi}) async { 17 | final String param = rawParam != null ? rawParam : jsonEncode(params); 18 | final Map tx = txInfo.toJson(); 19 | final res = await (service.estimateFees(tx, param, jsApi: jsApi)); 20 | return TxFeeEstimateResult.fromJson(res as Map); 21 | } 22 | 23 | // Future _testSendTx() async { 24 | // Completer c = new Completer(); 25 | // void onComplete(res) { 26 | // c.complete(res); 27 | // } 28 | // 29 | // Timer(Duration(seconds: 6), () => onComplete({'hash': '0x79867'})); 30 | // return c.future; 31 | // } 32 | 33 | /// Send tx, [params] will be ignored if we have [rawParam]. 34 | /// [onStatusChange] is a callback when tx status change. 35 | /// @return txHash [string] if tx finalized success. 36 | Future signAndSend( 37 | TxInfoData txInfo, 38 | List params, 39 | String password, { 40 | Function(String)? onStatusChange, 41 | String? rawParam, 42 | }) async { 43 | final param = rawParam != null ? rawParam : jsonEncode(params); 44 | final Map tx = txInfo.toJson(); 45 | print(tx); 46 | print(param); 47 | final res = await service.signAndSend( 48 | tx, 49 | param, 50 | password, 51 | onStatusChange ?? (status) => print(status), 52 | ); 53 | if (res?['error'] != null) { 54 | throw Exception(res?['error']); 55 | } 56 | return res ?? {}; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /example/lib/pages/dAppPage.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:polkawallet_sdk/polkawallet_sdk.dart'; 4 | import 'package:polkawallet_sdk/storage/keyring.dart'; 5 | import 'package:polkawallet_sdk/webviewWithExtension/webviewWithExtension.dart'; 6 | 7 | class DAppPage extends StatefulWidget { 8 | DAppPage(this.sdk, this.keyring); 9 | 10 | static const String route = '/extension/app'; 11 | 12 | final WalletSDK sdk; 13 | final Keyring keyring; 14 | 15 | @override 16 | _DAppPageState createState() => _DAppPageState(); 17 | } 18 | 19 | class _DAppPageState extends State { 20 | bool _loading = true; 21 | 22 | @override 23 | Widget build(BuildContext context) { 24 | final url = ModalRoute.of(context)?.settings.arguments as String; 25 | return Scaffold( 26 | appBar: AppBar( 27 | title: Text( 28 | url, 29 | style: TextStyle(fontSize: 16), 30 | ), 31 | centerTitle: true), 32 | body: SafeArea( 33 | child: Stack( 34 | children: [ 35 | WebViewWithExtension( 36 | widget.sdk.api, 37 | url, 38 | widget.keyring, 39 | onPageFinished: (url) { 40 | setState(() { 41 | _loading = false; 42 | }); 43 | }, 44 | onSignBytesRequest: (req) async { 45 | print(req); 46 | return null; 47 | }, 48 | onSignExtrinsicRequest: (req) async { 49 | print(req); 50 | return null; 51 | }, 52 | onConnectRequest: (req) async { 53 | print(req); 54 | return true; 55 | }, 56 | ), 57 | _loading ? Center(child: CupertinoActivityIndicator()) : Container() 58 | ], 59 | ), 60 | ), 61 | ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /lib/api/types/bridge/bridgeTokenBalance.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'bridgeTokenBalance.g.dart'; 4 | 5 | @JsonSerializable() 6 | class BridgeTokenBalance { 7 | String token; 8 | String free; 9 | String available; 10 | String locked; 11 | String reserved; 12 | int decimals; 13 | BridgeTokenBalance({ 14 | required this.token, 15 | required this.free, 16 | required this.available, 17 | required this.locked, 18 | required this.reserved, 19 | required this.decimals, 20 | }); 21 | 22 | static BridgeTokenBalance fromJson(Map json) => 23 | _$BridgeTokenBalanceFromJson(json); 24 | Map toJson() => _$BridgeTokenBalanceToJson(this); 25 | } 26 | 27 | @JsonSerializable() 28 | class BridgeAmountInputConfig { 29 | String token; 30 | String from; 31 | String to; 32 | String address; 33 | String minInput; 34 | String maxInput; 35 | BridgeDestFeeData destFee; 36 | String estimateFee; 37 | String xcmFee; 38 | BridgeAmountInputConfig({ 39 | required this.token, 40 | required this.from, 41 | required this.to, 42 | required this.address, 43 | required this.minInput, 44 | required this.maxInput, 45 | required this.destFee, 46 | required this.estimateFee, 47 | required this.xcmFee, 48 | }); 49 | 50 | static BridgeAmountInputConfig fromJson(Map json) => 51 | _$BridgeAmountInputConfigFromJson(json); 52 | Map toJson() => _$BridgeAmountInputConfigToJson(this); 53 | } 54 | 55 | @JsonSerializable() 56 | class BridgeDestFeeData { 57 | String token; 58 | String amount; 59 | int decimals; 60 | BridgeDestFeeData({ 61 | required this.token, 62 | required this.amount, 63 | required this.decimals, 64 | }); 65 | 66 | static BridgeDestFeeData fromJson(Map json) => 67 | _$BridgeDestFeeDataFromJson(json); 68 | Map toJson() => _$BridgeDestFeeDataToJson(this); 69 | } 70 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 31 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "io.polkawallet.www.example" 42 | minSdkVersion 19 43 | targetSdkVersion 31 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | } 47 | 48 | buildTypes { 49 | release { 50 | // TODO: Add your own signing config for the release build. 51 | // Signing with the debug keys for now, so `flutter run --release` works. 52 | signingConfig signingConfigs.debug 53 | } 54 | } 55 | } 56 | 57 | flutter { 58 | source '../..' 59 | } 60 | 61 | dependencies { 62 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 63 | } 64 | -------------------------------------------------------------------------------- /lib/api/types/gov/referendumInfoData.dart: -------------------------------------------------------------------------------- 1 | class ReferendumInfo extends _ReferendumInfo { 2 | static ReferendumInfo fromJson(Map json) { 3 | ReferendumInfo info = ReferendumInfo(); 4 | info.index = BigInt.parse(json['index'].toString()); 5 | info.imageHash = json['imageHash']; 6 | info.status = json['status']; 7 | info.image = json['image']; 8 | info.detail = json['detail']; 9 | 10 | info.isPassing = json['isPassing']; 11 | info.voteCountAye = json['voteCountAye']; 12 | info.voteCountNay = json['voteCountNay']; 13 | info.votedAye = json['votedAye'].toString(); 14 | info.votedNay = json['votedNay'].toString(); 15 | info.votedTotal = json['votedTotal'].toString(); 16 | info.changeAye = info.detail!['changes']['changeAye'].toString(); 17 | info.changeNay = info.detail!['changes']['changeNay'].toString(); 18 | 19 | info.userVoted = info.detail!['userVoted']; 20 | return info; 21 | } 22 | 23 | Map toJson() => { 24 | 'index': this.index, 25 | 'imageHash': this.imageHash, 26 | 'status': this.status, 27 | 'image': this.image, 28 | 'detail': this.detail, 29 | 'isPassing': this.isPassing, 30 | 'voteCountAye': this.voteCountAye, 31 | 'voteCountNay': this.voteCountNay, 32 | 'votedTotal': this.votedTotal, 33 | 'votedAye': this.votedAye, 34 | 'votedNay': this.votedNay, 35 | 'changeAye': this.changeAye, 36 | 'changeNay': this.changeNay, 37 | 'userVoted': this.userVoted, 38 | }; 39 | } 40 | 41 | abstract class _ReferendumInfo { 42 | BigInt? index; 43 | String? imageHash; 44 | 45 | bool? isPassing; 46 | int? voteCountAye; 47 | int? voteCountNay; 48 | String? votedAye; 49 | String? votedNay; 50 | String? votedTotal; 51 | String? changeAye; 52 | String? changeNay; 53 | 54 | Map? status; 55 | Map? image; 56 | Map? detail; 57 | 58 | Map? userVoted; 59 | } 60 | -------------------------------------------------------------------------------- /lib/api/types/walletConnect/payloadData.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'payloadData.g.dart'; 4 | 5 | @JsonSerializable(explicitToJson: true) 6 | class WCPayloadData extends _WCPayloadData { 7 | static WCPayloadData fromJson(Map json) => 8 | _$WCPayloadDataFromJson(Map.from(json)); 9 | Map toJson() => _$WCPayloadDataToJson(this); 10 | } 11 | 12 | abstract class _WCPayloadData { 13 | String? topic; 14 | String? chainId; 15 | WCPayload? payload; 16 | } 17 | 18 | @JsonSerializable() 19 | class WCPayload extends _WCPayload { 20 | static WCPayload fromJson(Map json) => 21 | _$WCPayloadFromJson(Map.from(json)); 22 | Map toJson() => _$WCPayloadToJson(this); 23 | } 24 | 25 | abstract class _WCPayload { 26 | int? id; 27 | String? method; 28 | List? params; 29 | } 30 | 31 | @JsonSerializable() 32 | class WCCallRequestData extends _WCCallRequestData { 33 | static WCCallRequestData fromJson(Map json) => 34 | _$WCCallRequestDataFromJson(Map.from(json)); 35 | Map toJson() => _$WCCallRequestDataToJson(this); 36 | } 37 | 38 | abstract class _WCCallRequestData { 39 | String? event; 40 | String? topic; 41 | int? id; 42 | List? params; 43 | } 44 | 45 | @JsonSerializable() 46 | class WCCallRequestParamItem extends _WCCallRequestParamItem { 47 | static WCCallRequestParamItem fromJson(Map json) => 48 | _$WCCallRequestParamItemFromJson(Map.from(json)); 49 | Map toJson() => _$WCCallRequestParamItemToJson(this); 50 | } 51 | 52 | abstract class _WCCallRequestParamItem { 53 | String? label; 54 | dynamic value; 55 | } 56 | 57 | @JsonSerializable() 58 | class WCCallRequestResult extends _WCCallRequestResult { 59 | static WCCallRequestResult fromJson(Map json) => 60 | _$WCCallRequestResultFromJson(Map.from(json)); 61 | Map toJson() => _$WCCallRequestResultToJson(this); 62 | } 63 | 64 | abstract class _WCCallRequestResult { 65 | String? result; 66 | String? error; 67 | } 68 | -------------------------------------------------------------------------------- /js_as_extension/src/index.js: -------------------------------------------------------------------------------- 1 | import { enable, handleResponse } from "@polkadot/extension-base/page"; 2 | import { injectExtension } from "@polkadot/extension-inject"; 3 | import { web3Accounts, web3Enable } from "@polkadot/extension-dapp"; 4 | import handlers from "./handlers"; 5 | 6 | // send message to JSChannel: assembly 7 | function send(path, data) { 8 | if (window.location.href.match("js_as_extension")) { 9 | console.log(path, data); 10 | } else { 11 | Extension.postMessage(JSON.stringify({ path, data })); 12 | } 13 | } 14 | send("log", "main js loaded"); 15 | window.send = send; 16 | 17 | // window.postMessage = (msg, source) => { 18 | // window.send(source, msg); 19 | // }; 20 | 21 | // setup a response listener (events created by the loader for extension responses) 22 | window.addEventListener("message", ({ data, source }) => { 23 | // only allow messages from our window, by the loader 24 | if (source !== window) { 25 | return; 26 | } 27 | 28 | if (data.origin === "content") { 29 | if (data.id) { 30 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 31 | handleResponse(data); 32 | } else { 33 | console.error("Missing id for response."); 34 | } 35 | } else if (data.origin === "page") { 36 | handlers.handleMsg(data); 37 | } 38 | }); 39 | 40 | injectExtension(enable, { 41 | name: "polkadot-js", 42 | version: "0.9.0", 43 | }); 44 | 45 | injectExtension(enable, { 46 | name: "polkawallet", 47 | version: "0.9.0", 48 | }); 49 | 50 | async function test() { 51 | // returns an array of all the injected sources 52 | // (this needs to be called first, before other requests) 53 | const allInjected = await web3Enable("my cool dapp"); 54 | send("log", allInjected); 55 | 56 | // returns an array of { address, meta: { name, source } } 57 | // meta.source contains the name of the extension that provides this account 58 | const allAccounts = await web3Accounts(); 59 | send("log", allAccounts); 60 | } 61 | 62 | window.walletExtension = { 63 | test, 64 | onAppResponse: handlers.onAppResponse, 65 | }; 66 | -------------------------------------------------------------------------------- /lib/api/types/txInfoData.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'txInfoData.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | TxInfoData _$TxInfoDataFromJson(Map json) => TxInfoData( 10 | json['module'] as String?, 11 | json['call'] as String?, 12 | json['sender'] == null 13 | ? null 14 | : TxSenderData.fromJson(json['sender'] as Map), 15 | tip: json['tip'] as String? ?? '0', 16 | isUnsigned: json['isUnsigned'] as bool? ?? false, 17 | proxy: json['proxy'] == null 18 | ? null 19 | : TxSenderData.fromJson(json['proxy'] as Map), 20 | txName: json['txName'] as String?, 21 | txHex: json['txHex'] as String?, 22 | ); 23 | 24 | Map _$TxInfoDataToJson(TxInfoData instance) => 25 | { 26 | 'module': instance.module, 27 | 'call': instance.call, 28 | 'sender': instance.sender?.toJson(), 29 | 'tip': instance.tip, 30 | 'txHex': instance.txHex, 31 | 'isUnsigned': instance.isUnsigned, 32 | 'proxy': instance.proxy?.toJson(), 33 | 'txName': instance.txName, 34 | }; 35 | 36 | TxSenderData _$TxSenderDataFromJson(Map json) => TxSenderData( 37 | json['address'] as String?, 38 | json['pubKey'] as String?, 39 | ); 40 | 41 | Map _$TxSenderDataToJson(TxSenderData instance) => 42 | { 43 | 'address': instance.address, 44 | 'pubKey': instance.pubKey, 45 | }; 46 | 47 | TxFeeEstimateResult _$TxFeeEstimateResultFromJson(Map json) => 48 | TxFeeEstimateResult() 49 | ..weight = json['weight'] 50 | ..partialFee = json['partialFee']; 51 | 52 | Map _$TxFeeEstimateResultToJson( 53 | TxFeeEstimateResult instance) => 54 | { 55 | 'weight': instance.weight, 56 | 'partialFee': instance.partialFee, 57 | }; 58 | -------------------------------------------------------------------------------- /lib/api/types/bridge/bridgeChainData.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'bridgeChainData.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | BridgeChainData _$BridgeChainDataFromJson(Map json) => 10 | BridgeChainData( 11 | id: json['id'] as String, 12 | display: json['display'] as String, 13 | icon: json['icon'] as String, 14 | paraChainId: json['paraChainId'] as int, 15 | ss58Prefix: json['ss58Prefix'] as int, 16 | ); 17 | 18 | Map _$BridgeChainDataToJson(BridgeChainData instance) => 19 | { 20 | 'id': instance.id, 21 | 'display': instance.display, 22 | 'icon': instance.icon, 23 | 'paraChainId': instance.paraChainId, 24 | 'ss58Prefix': instance.ss58Prefix, 25 | }; 26 | 27 | BridgeRouteData _$BridgeRouteDataFromJson(Map json) => 28 | BridgeRouteData( 29 | from: json['from'] as String, 30 | to: json['to'] as String, 31 | token: json['token'] as String, 32 | ); 33 | 34 | Map _$BridgeRouteDataToJson(BridgeRouteData instance) => 35 | { 36 | 'from': instance.from, 37 | 'to': instance.to, 38 | 'token': instance.token, 39 | }; 40 | 41 | BridgeNetworkProperties _$BridgeNetworkPropertiesFromJson( 42 | Map json) => 43 | BridgeNetworkProperties( 44 | ss58Format: json['ss58Format'] as int, 45 | tokenDecimals: (json['tokenDecimals'] as List) 46 | .map((e) => e as int) 47 | .toList(), 48 | tokenSymbol: (json['tokenSymbol'] as List) 49 | .map((e) => e as String) 50 | .toList(), 51 | ); 52 | 53 | Map _$BridgeNetworkPropertiesToJson( 54 | BridgeNetworkProperties instance) => 55 | { 56 | 'ss58Format': instance.ss58Format, 57 | 'tokenDecimals': instance.tokenDecimals, 58 | 'tokenSymbol': instance.tokenSymbol, 59 | }; 60 | -------------------------------------------------------------------------------- /lib/service/recovery.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:polkawallet_sdk/service/index.dart'; 4 | 5 | class ServiceRecovery { 6 | ServiceRecovery(this.serviceRoot); 7 | 8 | final SubstrateService serviceRoot; 9 | 10 | Future queryRecoverable(String address) async { 11 | // address = "J4sW13h2HNerfxTzPGpLT66B3HVvuU32S6upxwSeFJQnAzg"; 12 | dynamic res = await serviceRoot.webView! 13 | .evalJavascript('api.query.recovery.recoverable("$address")'); 14 | if (res != null) { 15 | res['address'] = address; 16 | } 17 | return res; 18 | } 19 | 20 | Future queryRecoverableList(List addresses) async { 21 | final queries = 22 | addresses.map((e) => 'api.query.recovery.recoverable("$e")').toList(); 23 | final dynamic ls = await serviceRoot.webView! 24 | .evalJavascript('Promise.all([${queries.join(',')}])'); 25 | 26 | final res = []; 27 | ls.asMap().forEach((k, v) { 28 | if (v != null) { 29 | v['address'] = addresses[k]; 30 | } 31 | res.add(v); 32 | }); 33 | 34 | return res; 35 | } 36 | 37 | Future queryActiveRecoveryAttempts( 38 | String address, List addressNew) async { 39 | List queries = addressNew 40 | .map((e) => 'api.query.recovery.activeRecoveries("$address", "$e")') 41 | .toList(); 42 | final res = await serviceRoot.webView! 43 | .evalJavascript('Promise.all([${queries.join(',')}])'); 44 | return res; 45 | } 46 | 47 | Future queryActiveRecoveries( 48 | List addresses, String addressNew) async { 49 | List queries = addresses 50 | .map((e) => 'api.query.recovery.activeRecoveries("$e", "$addressNew")') 51 | .toList(); 52 | final res = await serviceRoot.webView! 53 | .evalJavascript('Promise.all([${queries.join(',')}])'); 54 | return res; 55 | } 56 | 57 | Future queryRecoveryProxies(List addresses) async { 58 | List queries = 59 | addresses.map((e) => 'api.query.recovery.proxy("$e")').toList(); 60 | final res = await serviceRoot.webView!.evalJavascript( 61 | 'Promise.all([${queries.join(',')}])', 62 | allowRepeat: true, 63 | ); 64 | return res; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /js_api/src/service/eth/settings.ts: -------------------------------------------------------------------------------- 1 | import Web3 from "web3"; 2 | import { AbiItem } from "web3-utils"; 3 | 4 | let web3: Web3; 5 | 6 | export const erc20Abi: AbiItem[] = [ 7 | { 8 | constant: true, 9 | inputs: [], 10 | name: "name", 11 | outputs: [{ internalType: "string", name: "", type: "string" }], 12 | payable: false, 13 | stateMutability: "view", 14 | type: "function", 15 | }, 16 | { 17 | constant: true, 18 | inputs: [], 19 | name: "symbol", 20 | outputs: [{ internalType: "string", name: "", type: "string" }], 21 | payable: false, 22 | stateMutability: "view", 23 | type: "function", 24 | }, 25 | { 26 | constant: true, 27 | inputs: [], 28 | name: "decimals", 29 | outputs: [{ internalType: "uint8", name: "", type: "uint8" }], 30 | payable: false, 31 | stateMutability: "view", 32 | type: "function", 33 | }, 34 | { 35 | constant: true, 36 | inputs: [{ internalType: "address", name: "", type: "address" }], 37 | name: "balanceOf", 38 | outputs: [{ internalType: "uint256", name: "", type: "uint256" }], 39 | payable: false, 40 | stateMutability: "view", 41 | type: "function", 42 | }, 43 | { 44 | constant: false, 45 | inputs: [ 46 | { internalType: "address", name: "dst", type: "address" }, 47 | { internalType: "uint256", name: "wad", type: "uint256" }, 48 | ], 49 | name: "transfer", 50 | outputs: [{ internalType: "bool", name: "", type: "bool" }], 51 | payable: false, 52 | stateMutability: "nonpayable", 53 | type: "function", 54 | }, 55 | { 56 | anonymous: false, 57 | inputs: [ 58 | { indexed: true, internalType: "address", name: "src", type: "address" }, 59 | { indexed: true, internalType: "address", name: "dst", type: "address" }, 60 | { indexed: false, internalType: "uint256", name: "wad", type: "uint256" }, 61 | ], 62 | name: "Transfer", 63 | type: "event", 64 | }, 65 | ]; 66 | 67 | export async function connect(url: string) { 68 | if (!web3) { 69 | web3 = new Web3(url); 70 | } else { 71 | web3.setProvider(url); 72 | } 73 | const chainId = await web3.eth.getChainId(); 74 | return { chainId }; 75 | } 76 | 77 | export function getWeb3() { 78 | if (!web3) { 79 | web3 = new Web3(); 80 | } 81 | return web3; 82 | } 83 | -------------------------------------------------------------------------------- /lib/service/staking.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:convert'; 3 | 4 | import 'package:polkawallet_sdk/service/index.dart'; 5 | 6 | class ServiceStaking { 7 | ServiceStaking(this.serviceRoot); 8 | 9 | final SubstrateService serviceRoot; 10 | 11 | Future queryElectedInfo() async { 12 | dynamic data = await serviceRoot.webView! 13 | .evalJavascript('staking.querySortedTargets(api)', allowRepeat: false); 14 | return data; 15 | } 16 | 17 | Future queryNominations() async { 18 | dynamic data = await serviceRoot.webView! 19 | .evalJavascript('staking.queryNominations(api)', allowRepeat: false); 20 | return data; 21 | } 22 | 23 | Future queryNominationsCount() async { 24 | dynamic data = await serviceRoot.webView!.evalJavascript( 25 | 'staking.queryNominationsCount(api)', 26 | allowRepeat: false); 27 | return data; 28 | } 29 | 30 | Future queryBonded(List pubKeys) async { 31 | dynamic res = await serviceRoot.webView!.evalJavascript( 32 | 'account.queryAccountsBonded(api, ${jsonEncode(pubKeys)})'); 33 | return res; 34 | } 35 | 36 | Future queryOwnStashInfo(String accountId) async { 37 | dynamic data = await serviceRoot.webView! 38 | .evalJavascript('staking.getOwnStashInfo(api, "$accountId")'); 39 | return data; 40 | } 41 | 42 | Future loadValidatorRewardsData(String validatorId) async { 43 | dynamic data = await serviceRoot.webView!.evalJavascript( 44 | 'staking.loadValidatorRewardsData(api, "$validatorId")'); 45 | return data; 46 | } 47 | 48 | Future getAccountRewardsEraOptions() async { 49 | final dynamic res = await serviceRoot.webView! 50 | .evalJavascript('staking.getAccountRewardsEraOptions(api)'); 51 | return res; 52 | } 53 | 54 | // this query takes extremely long time 55 | Future fetchAccountRewards(String address, int eras) async { 56 | final dynamic res = await serviceRoot.webView!.evalJavascript( 57 | 'staking.loadAccountRewardsData(api, "$address", $eras)'); 58 | return res; 59 | } 60 | 61 | Future getSlashingSpans(String stashId) async { 62 | final dynamic spans = await serviceRoot.webView! 63 | .evalJavascript('staking.getSlashingSpans(api, "$stashId")'); 64 | return spans; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: polkawallet_sdk 2 | description: Flutter SDK for building plugin package for polkawallet. 3 | version: 0.6.6 4 | homepage: https://polkawallet.io 5 | 6 | environment: 7 | sdk: '>=2.12.0 <3.0.0' 8 | flutter: ">=1.17.0" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | http: ^0.13.5 14 | webview_flutter: ^4.0.7 15 | flutter_inappwebview: 16 | git: 17 | url: https://github.com/RomeroYang/flutter_inappwebview.git 18 | ref: 200ca53154d719efce1a2f7c4d49d8293d8dc579 19 | shared_preferences: ^2.0.7 20 | get_storage: ^2.1.1 21 | json_annotation: ^4.8.0 22 | flutter_aes_ecb_pkcs5: ^0.1.2 23 | convert: ^3.1.1 24 | mobx: ^2.1.4 25 | bip39: ^1.0.6 26 | web3dart: ^2.3.5 27 | url_launcher: ^6.1.10 28 | 29 | dev_dependencies: 30 | mobx_codegen: ^2.1.1 31 | flutter_test: 32 | sdk: flutter 33 | build_runner: ^2.3.3 34 | json_serializable: ^6.6.1 35 | 36 | # For information on the generic Dart part of this file, see the 37 | # following page: https://dart.dev/tools/pub/pubspec 38 | 39 | # The following section is specific to Flutter. 40 | flutter: 41 | 42 | # To add assets to your package, add an assets section, like this: 43 | assets: 44 | - assets/ 45 | - js_as_extension/dist/main.js 46 | - js_as_extension/dist/ethereum.js 47 | 48 | # For details regarding assets in packages, see 49 | # https://flutter.dev/assets-and-images/#from-packages 50 | # 51 | # An image asset can refer to one or more resolution-specific "variants", see 52 | # https://flutter.dev/assets-and-images/#resolution-aware. 53 | 54 | # To add custom fonts to your package, add a fonts section here, 55 | # in this "flutter" section. Each entry in this list should have a 56 | # "family" key with the font family name, and a "fonts" key with a 57 | # list giving the asset and other descriptors for the font. For 58 | # example: 59 | # fonts: 60 | # - family: Schyler 61 | # fonts: 62 | # - asset: fonts/Schyler-Regular.ttf 63 | # - asset: fonts/Schyler-Italic.ttf 64 | # style: italic 65 | # - family: Trajan Pro 66 | # fonts: 67 | # - asset: fonts/TrajanPro.ttf 68 | # - asset: fonts/TrajanPro_Bold.ttf 69 | # weight: 700 70 | # 71 | # For details regarding fonts in packages, see 72 | # https://flutter.dev/custom-fonts/#from-packages 73 | -------------------------------------------------------------------------------- /lib/service/account.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:convert'; 3 | 4 | import 'package:polkawallet_sdk/service/index.dart'; 5 | 6 | class ServiceAccount { 7 | ServiceAccount(this.serviceRoot); 8 | 9 | final SubstrateService serviceRoot; 10 | 11 | /// encode addresses to publicKeys 12 | Future encodeAddress(List pubKeys, ss58List) async { 13 | final dynamic res = await serviceRoot.webView!.evalJavascript( 14 | 'account.encodeAddress(${jsonEncode(pubKeys)}, ${jsonEncode(ss58List)})'); 15 | return res; 16 | } 17 | 18 | /// decode addresses to publicKeys 19 | Future decodeAddress(List addresses) async { 20 | final dynamic res = await serviceRoot.webView! 21 | .evalJavascript('account.decodeAddress(${jsonEncode(addresses)})'); 22 | return res; 23 | } 24 | 25 | /// check address matches ss58Format 26 | Future checkAddressFormat(String address, int ss58) async { 27 | final dynamic res = await serviceRoot.webView! 28 | .evalJavascript('account.checkAddressFormat("$address", $ss58)'); 29 | return res; 30 | } 31 | 32 | /// query balance 33 | Future queryBalance(String? address) async { 34 | final dynamic res = await serviceRoot.webView! 35 | .evalJavascript('account.getBalance(api, "$address")'); 36 | return res; 37 | } 38 | 39 | /// Get on-chain account info of addresses 40 | Future queryIndexInfo(List addresses) async { 41 | final dynamic res = await serviceRoot.webView!.evalJavascript( 42 | 'account.getAccountIndex(api, ${jsonEncode(addresses)})'); 43 | return res; 44 | } 45 | 46 | /// query address with account index 47 | Future queryAddressWithAccountIndex(String index, int? ss58) async { 48 | final res = await serviceRoot.webView!.evalJavascript( 49 | 'account.queryAddressWithAccountIndex(api, "$index", $ss58)'); 50 | return res; 51 | } 52 | 53 | Future getPubKeyIcons(List keys) async { 54 | final dynamic res = await serviceRoot.webView! 55 | .evalJavascript('account.genPubKeyIcons(${jsonEncode(keys)})'); 56 | return res; 57 | } 58 | 59 | Future getAddressIcons(List addresses) async { 60 | final dynamic res = await serviceRoot.webView! 61 | .evalJavascript('account.genIcons(${jsonEncode(addresses)})'); 62 | return res; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /lib/webviewWithExtension/types/signExtrinsicParam.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'signExtrinsicParam.g.dart'; 4 | 5 | @JsonSerializable(explicitToJson: true) 6 | class SignAsExtensionParam extends _SignAsExtensionParam { 7 | static SignAsExtensionParam fromJson(Map json) => 8 | _$SignAsExtensionParamFromJson(json); 9 | Map toJson() => _$SignAsExtensionParamToJson(this); 10 | } 11 | 12 | abstract class _SignAsExtensionParam { 13 | String? id; 14 | String? url; 15 | String? msgType; 16 | Map? request; 17 | } 18 | 19 | @JsonSerializable() 20 | class SignExtrinsicRequest extends _SignExtrinsicRequest { 21 | static SignExtrinsicRequest fromJson(Map json) => 22 | _$SignExtrinsicRequestFromJson(json); 23 | Map toJson() => _$SignExtrinsicRequestToJson(this); 24 | } 25 | 26 | abstract class _SignExtrinsicRequest { 27 | String? address; 28 | String? blockHash; 29 | String? blockNumber; 30 | String? era; 31 | String? genesisHash; 32 | String? method; 33 | String? nonce; 34 | List? signedExtensions; 35 | String? specVersion; 36 | String? tip; 37 | String? transactionVersion; 38 | int? version; 39 | Map? payload; 40 | } 41 | 42 | @JsonSerializable() 43 | class SignBytesRequest extends _SignBytesRequest { 44 | static SignBytesRequest fromJson(Map json) => 45 | _$SignBytesRequestFromJson(json); 46 | Map toJson() => _$SignBytesRequestToJson(this); 47 | } 48 | 49 | abstract class _SignBytesRequest { 50 | String? address; 51 | String? data; 52 | String? type; 53 | } 54 | 55 | @JsonSerializable() 56 | class ExtensionSignResult extends _ExtensionSignResult { 57 | static ExtensionSignResult fromJson(Map json) => 58 | _$ExtensionSignResultFromJson(json); 59 | Map toJson() => _$ExtensionSignResultToJson(this); 60 | } 61 | 62 | abstract class _ExtensionSignResult { 63 | String? id; 64 | String? signature; 65 | } 66 | 67 | @JsonSerializable() 68 | class DAppConnectParam extends _DAppConnectParam { 69 | static DAppConnectParam fromJson(Map json) => 70 | _$DAppConnectParamFromJson(json); 71 | Map toJson() => _$DAppConnectParamToJson(this); 72 | } 73 | 74 | abstract class _DAppConnectParam { 75 | String? id; 76 | String? url; 77 | } 78 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - flutter_aes_ecb_pkcs5 (0.0.1): 4 | - Flutter 5 | - flutter_inappwebview (0.0.1): 6 | - Flutter 7 | - flutter_inappwebview/Core (= 0.0.1) 8 | - OrderedSet (~> 5.0) 9 | - flutter_inappwebview/Core (0.0.1): 10 | - Flutter 11 | - OrderedSet (~> 5.0) 12 | - OrderedSet (5.0.0) 13 | - path_provider_ios (0.0.1): 14 | - Flutter 15 | - shared_preferences_ios (0.0.1): 16 | - Flutter 17 | - url_launcher_ios (0.0.1): 18 | - Flutter 19 | - webview_flutter_wkwebview (0.0.1): 20 | - Flutter 21 | 22 | DEPENDENCIES: 23 | - Flutter (from `Flutter`) 24 | - flutter_aes_ecb_pkcs5 (from `.symlinks/plugins/flutter_aes_ecb_pkcs5/ios`) 25 | - flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`) 26 | - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) 27 | - shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`) 28 | - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) 29 | - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`) 30 | 31 | SPEC REPOS: 32 | trunk: 33 | - OrderedSet 34 | 35 | EXTERNAL SOURCES: 36 | Flutter: 37 | :path: Flutter 38 | flutter_aes_ecb_pkcs5: 39 | :path: ".symlinks/plugins/flutter_aes_ecb_pkcs5/ios" 40 | flutter_inappwebview: 41 | :path: ".symlinks/plugins/flutter_inappwebview/ios" 42 | path_provider_ios: 43 | :path: ".symlinks/plugins/path_provider_ios/ios" 44 | shared_preferences_ios: 45 | :path: ".symlinks/plugins/shared_preferences_ios/ios" 46 | url_launcher_ios: 47 | :path: ".symlinks/plugins/url_launcher_ios/ios" 48 | webview_flutter_wkwebview: 49 | :path: ".symlinks/plugins/webview_flutter_wkwebview/ios" 50 | 51 | SPEC CHECKSUMS: 52 | Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 53 | flutter_aes_ecb_pkcs5: fb682a7bb13f29cfbb33f88f7e1ed2211eacf5db 54 | flutter_inappwebview: 3d32228f1304635e7c028b0d4252937730bbc6cf 55 | OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c 56 | path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 57 | shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad 58 | url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de 59 | webview_flutter_wkwebview: 2e2d318f21a5e036e2c3f26171342e95908bd60a 60 | 61 | PODFILE CHECKSUM: d52245ce949ccd5584a76a8c2e0d80788ffe80ee 62 | 63 | COCOAPODS: 1.14.3 64 | -------------------------------------------------------------------------------- /lib/api/types/evmTxData.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'evmTxData.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | EvmTxData _$EvmTxDataFromJson(Map json) => EvmTxData( 10 | value: json['value'] as String?, 11 | blockHash: json['blockHash'] as String?, 12 | blockNumber: json['blockNumber'] as String?, 13 | confirmations: json['confirmations'] as String?, 14 | contractAddress: json['contractAddress'] as String?, 15 | cumulativeGasUsed: json['cumulativeGasUsed'] as String?, 16 | from: json['from'] as String?, 17 | gas: json['gas'] as String?, 18 | gasPrice: json['gasPrice'] as String?, 19 | gasUsed: json['gasUsed'] as String?, 20 | hash: json['hash'] as String?, 21 | input: json['input'] as String?, 22 | logIndex: json['logIndex'] as String?, 23 | nonce: json['nonce'] as String?, 24 | timeStamp: json['timeStamp'] as String?, 25 | to: json['to'] as String?, 26 | tokenDecimal: json['tokenDecimal'] as String?, 27 | tokenName: json['tokenName'] as String?, 28 | tokenSymbol: json['tokenSymbol'] as String?, 29 | transactionIndex: json['transactionIndex'] as String?, 30 | isError: json['isError'] as String?, 31 | ); 32 | 33 | Map _$EvmTxDataToJson(EvmTxData instance) => { 34 | 'value': instance.value, 35 | 'blockHash': instance.blockHash, 36 | 'blockNumber': instance.blockNumber, 37 | 'confirmations': instance.confirmations, 38 | 'contractAddress': instance.contractAddress, 39 | 'cumulativeGasUsed': instance.cumulativeGasUsed, 40 | 'from': instance.from, 41 | 'gas': instance.gas, 42 | 'gasPrice': instance.gasPrice, 43 | 'gasUsed': instance.gasUsed, 44 | 'hash': instance.hash, 45 | 'input': instance.input, 46 | 'logIndex': instance.logIndex, 47 | 'nonce': instance.nonce, 48 | 'timeStamp': instance.timeStamp, 49 | 'to': instance.to, 50 | 'tokenDecimal': instance.tokenDecimal, 51 | 'tokenName': instance.tokenName, 52 | 'tokenSymbol': instance.tokenSymbol, 53 | 'transactionIndex': instance.transactionIndex, 54 | 'isError': instance.isError, 55 | }; 56 | -------------------------------------------------------------------------------- /lib/api/types/staking/ownStashInfo.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'ownStashInfo.g.dart'; 4 | 5 | @JsonSerializable() 6 | class OwnStashInfoData extends _OwnStashInfoData { 7 | static OwnStashInfoData fromJson(Map json) => 8 | _$OwnStashInfoDataFromJson(json); 9 | Map toJson() => _$OwnStashInfoDataToJson(this); 10 | } 11 | 12 | abstract class _OwnStashInfoData { 13 | LedgerInfoData? account; 14 | String? controllerId; 15 | String? destination; 16 | int? destinationId; 17 | Map? exposure; 18 | String? hexSessionIdNext; 19 | String? hexSessionIdQueue; 20 | bool? isOwnController; 21 | bool? isOwnStash; 22 | bool? isStashNominating; 23 | bool? isStashValidating; 24 | List? nominating; 25 | List? sessionIds; 26 | Map? stakingLedger; 27 | String? stashId; 28 | Map? validatorPrefs; 29 | NomineesInfoData? inactives; 30 | Map? unbondings; 31 | } 32 | 33 | @JsonSerializable() 34 | class NomineesInfoData extends _NomineesInfoData { 35 | static NomineesInfoData fromJson(Map json) => 36 | _$NomineesInfoDataFromJson(json); 37 | Map toJson() => _$NomineesInfoDataToJson(this); 38 | } 39 | 40 | abstract class _NomineesInfoData { 41 | List? nomsActive; 42 | List? nomsChilled; 43 | List? nomsInactive; 44 | List? nomsOver; 45 | List? nomsWaiting; 46 | } 47 | 48 | @JsonSerializable() 49 | class LedgerInfoData extends _LedgerInfoData { 50 | static LedgerInfoData fromJson(Map json) => 51 | _$LedgerInfoDataFromJson(json); 52 | Map toJson() => _$LedgerInfoDataToJson(this); 53 | } 54 | 55 | abstract class _LedgerInfoData { 56 | String? accountId; 57 | String? controllerId; 58 | String? stashId; 59 | Map? exposure; 60 | Map? stakingLedger; 61 | Map? validatorPrefs; 62 | dynamic redeemable; 63 | } 64 | 65 | @JsonSerializable() 66 | class UnbondingInfoData extends _UnbondingInfoData { 67 | static UnbondingInfoData fromJson(Map json) => 68 | _$UnbondingInfoDataFromJson(json); 69 | Map toJson() => _$UnbondingInfoDataToJson(this); 70 | } 71 | 72 | abstract class _UnbondingInfoData { 73 | List? mapped; 74 | dynamic total; 75 | } 76 | -------------------------------------------------------------------------------- /js_api/src/service/setting.ts: -------------------------------------------------------------------------------- 1 | import { ApiPromise } from "@polkadot/api"; 2 | import { SubstrateNetworkKeys } from "../constants/networkSpect"; 3 | 4 | const MAX_NOMINATIONS = 16; 5 | 6 | /** 7 | * subscribe messages of network state. 8 | * 9 | * @param {Function} method i.e. api.derive.chain.bestNumber 10 | * @param {List} params 11 | * @param {String} msgChannel 12 | * @param {Function} transfrom result data transfrom 13 | */ 14 | export async function subscribeMessage(method: any, params: any[], msgChannel: string, transfrom: Function) { 15 | return method(...params, (res: any) => { 16 | const data = transfrom ? transfrom(res) : res; 17 | (window).send(msgChannel, data); 18 | }).then((unsub: () => void) => { 19 | const unsubFuncName = `unsub${msgChannel}`; 20 | (window)[unsubFuncName] = unsub; 21 | return {}; 22 | }); 23 | } 24 | 25 | /** 26 | * get consts of network. 27 | */ 28 | export async function getNetworkConst(api: ApiPromise) { 29 | return { 30 | auctions: { 31 | endingPeriod: api.consts.auctions?.endingPeriod, 32 | }, 33 | babe: { 34 | expectedBlockTime: api.consts.babe?.expectedBlockTime, 35 | }, 36 | balances: { 37 | existentialDeposit: api.consts.balances?.existentialDeposit, 38 | }, 39 | staking: { 40 | maxNominations: api.consts.staking?.maxNominations || MAX_NOMINATIONS, 41 | maxNominatorRewardedPerValidator: api.consts.staking?.maxNominatorRewardedPerValidator || MAX_NOMINATIONS, 42 | }, 43 | timestamp: { 44 | minimumPeriod: api.consts.timestamp?.minimumPeriod, 45 | }, 46 | treasury: { 47 | proposalBondMinimum: api.consts.treasury?.proposalBondMinimum, 48 | proposalBond: api.consts.treasury?.proposalBond, 49 | spendPeriod: api.consts.treasury?.spendPeriod, 50 | }, 51 | }; 52 | } 53 | 54 | /** 55 | * get network properties, and replace polkadot decimals with const 10. 56 | */ 57 | export async function getNetworkProperties(api: ApiPromise) { 58 | const chainProperties = await api.rpc.system.properties(); 59 | const genesisHash = api.genesisHash.toHuman(); 60 | return genesisHash == SubstrateNetworkKeys.POLKADOT 61 | ? api.registry.createType("ChainProperties", { 62 | ...chainProperties.toJSON(), 63 | tokenDecimals: [10], 64 | tokenSymbol: ["DOT"], 65 | genesisHash, 66 | }) 67 | : { ...chainProperties.toJSON(), genesisHash }; 68 | } 69 | -------------------------------------------------------------------------------- /lib/api/apiStaking.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:polkawallet_sdk/api/api.dart'; 4 | import 'package:polkawallet_sdk/api/types/staking/accountBondedInfo.dart'; 5 | import 'package:polkawallet_sdk/api/types/staking/ownStashInfo.dart'; 6 | import 'package:polkawallet_sdk/service/staking.dart'; 7 | 8 | class ApiStaking { 9 | ApiStaking(this.apiRoot, this.service); 10 | 11 | final PolkawalletApi apiRoot; 12 | final ServiceStaking service; 13 | 14 | Future queryElectedInfo() async { 15 | Map? data = await service.queryElectedInfo(); 16 | return data; 17 | } 18 | 19 | Future queryNominations() async { 20 | final res = await service.queryNominations(); 21 | return res; 22 | } 23 | 24 | Future queryNominationsCount() async { 25 | final res = await service.queryNominationsCount(); 26 | return res; 27 | } 28 | 29 | /// query staking stash-controller relationship of a list of pubKeys, 30 | /// return list of [pubKey, controllerAddress, stashAddress]. 31 | Future> queryBonded( 32 | List pubKeys) async { 33 | if (pubKeys.length == 0) { 34 | return {}; 35 | } 36 | final res = Map(); 37 | final List data = 38 | await (service.queryBonded(pubKeys) as FutureOr>); 39 | data.forEach((e) { 40 | res[e[0]] = AccountBondedInfo(e[0], e[1], e[2]); 41 | }); 42 | return res; 43 | } 44 | 45 | Future queryOwnStashInfo(String accountId) async { 46 | final Map data = await (service.queryOwnStashInfo(accountId)); 47 | return OwnStashInfoData.fromJson( 48 | Map.of(data as Map)); 49 | } 50 | 51 | Future loadValidatorRewardsData(String validatorId) async { 52 | Map? data = await service.loadValidatorRewardsData(validatorId); 53 | return data; 54 | } 55 | 56 | Future getAccountRewardsEraOptions() async { 57 | final List? res = await service.getAccountRewardsEraOptions(); 58 | return res; 59 | } 60 | 61 | // this query takes extremely long time 62 | Future queryAccountRewards(String address, int eras) async { 63 | final Map? res = await service.fetchAccountRewards(address, eras); 64 | return res; 65 | } 66 | 67 | Future getSlashingSpans(String stashId) async { 68 | final int? spans = await service.getSlashingSpans(stashId); 69 | return spans; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /js_api/src/service/walletconnect/v1/helpers/api.ts: -------------------------------------------------------------------------------- 1 | import axios, { AxiosInstance } from "axios"; 2 | import { IJsonRpcRequest } from "./types"; 3 | import { IAssetData, IGasPrices, IParsedTx } from "./types"; 4 | import { payloadId, getChainData } from "./utilities"; 5 | 6 | const api: AxiosInstance = axios.create({ 7 | baseURL: "https://ethereum-api.xyz", 8 | timeout: 30000, // 30 secs 9 | headers: { 10 | Accept: "application/json", 11 | "Content-Type": "application/json", 12 | }, 13 | }); 14 | 15 | export const apiSendTransaction = async (txParams: any, chainId: number): Promise => { 16 | const rpcUrl = getChainData(chainId).rpc_url; 17 | 18 | if (!rpcUrl && typeof rpcUrl !== "string") { 19 | throw new Error("Invalid or missing rpc url"); 20 | } 21 | 22 | const response = await axios.post(rpcUrl, { 23 | jsonrpc: "2.0", 24 | id: payloadId(), 25 | method: "eth_sendTransaction", 26 | params: [txParams], 27 | }); 28 | 29 | const result = response.data.result; 30 | return result; 31 | }; 32 | 33 | export async function apiGetAccountAssets(address: string, chainId: number): Promise { 34 | const response = await api.get(`/account-assets?address=${address}&chainId=${chainId}`); 35 | const { result } = response.data; 36 | return result; 37 | } 38 | 39 | export async function apiGetAccountTransactions(address: string, chainId: number): Promise { 40 | const response = await api.get(`/account-transactions?address=${address}&chainId=${chainId}`); 41 | const { result } = response.data; 42 | return result; 43 | } 44 | 45 | export const apiGetAccountNonce = async (address: string, chainId: number): Promise => { 46 | const response = await api.get(`/account-nonce?address=${address}&chainId=${chainId}`); 47 | const { result } = response.data; 48 | return result; 49 | }; 50 | 51 | export const apiGetGasPrices = async (): Promise => { 52 | const response = await api.get(`/gas-prices`); 53 | const { result } = response.data; 54 | return result; 55 | }; 56 | 57 | export const apiGetBlockNumber = async (chainId: number): Promise => { 58 | const response = await api.get(`/block-number?chainId=${chainId}`); 59 | const { result } = response.data; 60 | return result; 61 | }; 62 | 63 | export const apiGetCustomRequest = async (chainId: number, customRpc: Partial): Promise => { 64 | const response = await api.post(`config-request?chainId=${chainId}`, customRpc); 65 | const { result } = response.data; 66 | return result; 67 | }; 68 | -------------------------------------------------------------------------------- /js_as_extension/src/handlers.js: -------------------------------------------------------------------------------- 1 | const EXTENSION_MSG_PATH = "extensionRequest"; 2 | 3 | const _msgCompleters = {}; 4 | 5 | // send request to host app 6 | async function requestApp({ id, message, request }) { 7 | return new Promise((resolve, reject) => { 8 | _msgCompleters[message + id] = { resolve, reject }; 9 | window.send(EXTENSION_MSG_PATH, { 10 | id, 11 | msgType: message, 12 | request, 13 | url: window.location.href, 14 | }); 15 | }); 16 | } 17 | 18 | // get response from host app 19 | function onAppResponse(msgType, response, error) { 20 | if (_msgCompleters[msgType]) { 21 | if (error) { 22 | _msgCompleters[msgType].reject(error); 23 | } else { 24 | _msgCompleters[msgType].resolve(response); 25 | } 26 | } 27 | } 28 | 29 | // send message to dapp page as extension-content 30 | function _postResponse(data) { 31 | window.postMessage({ ...data, origin: "content" }, "*"); 32 | } 33 | 34 | // handle message from dapp page as extension-content 35 | async function handleMsg(data) { 36 | let response; 37 | switch (data.message) { 38 | case "pub(authorize.tab)": 39 | // get auth result from host app 40 | response = await requestApp(data); 41 | // always approve extension auth 42 | return _postResponse({ id: data.id, response }); 43 | case "pub(accounts.list)": 44 | // get accounts from host app 45 | response = await requestApp(data); 46 | // then send result back to dapp page 47 | return _postResponse({ id: data.id, response }); 48 | case "pub(metadata.list)": 49 | // we dont need this function, so return false 50 | return _postResponse({ id: data.id, response: false }); 51 | case "pub(metadata.provide)": 52 | // we dont need this function, so return true 53 | return _postResponse({ id: data.id, response: true }); 54 | case "pub(accounts.subscribe)": 55 | // // get accounts from host app 56 | requestApp(data).then((subscription) => { 57 | // then send result back to dapp page 58 | _postResponse({ id: data.id, subscription }); 59 | }); 60 | return _postResponse({ id: data.id, response: true }); 61 | case "pub(bytes.sign)": 62 | case "pub(extrinsic.sign)": 63 | try { 64 | response = await requestApp(data); 65 | return _postResponse({ id: data.id, response }); 66 | } catch (err) { 67 | return _postResponse({ id: data.id, error: err.message }); 68 | } 69 | default: 70 | throw new Error(`Unable to handle message: ${data.message}`); 71 | } 72 | } 73 | 74 | export default { 75 | handleMsg, 76 | onAppResponse, 77 | }; 78 | -------------------------------------------------------------------------------- /lib/api/types/bridge/bridgeTokenBalance.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'bridgeTokenBalance.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | BridgeTokenBalance _$BridgeTokenBalanceFromJson(Map json) => 10 | BridgeTokenBalance( 11 | token: json['token'] as String, 12 | free: json['free'] as String, 13 | available: json['available'] as String, 14 | locked: json['locked'] as String, 15 | reserved: json['reserved'] as String, 16 | decimals: json['decimals'] as int, 17 | ); 18 | 19 | Map _$BridgeTokenBalanceToJson(BridgeTokenBalance instance) => 20 | { 21 | 'token': instance.token, 22 | 'free': instance.free, 23 | 'available': instance.available, 24 | 'locked': instance.locked, 25 | 'reserved': instance.reserved, 26 | 'decimals': instance.decimals, 27 | }; 28 | 29 | BridgeAmountInputConfig _$BridgeAmountInputConfigFromJson( 30 | Map json) => 31 | BridgeAmountInputConfig( 32 | token: json['token'] as String, 33 | from: json['from'] as String, 34 | to: json['to'] as String, 35 | address: json['address'] as String, 36 | minInput: json['minInput'] as String, 37 | maxInput: json['maxInput'] as String, 38 | destFee: 39 | BridgeDestFeeData.fromJson(json['destFee'] as Map), 40 | estimateFee: json['estimateFee'] as String, 41 | xcmFee: json['xcmFee'] as String, 42 | ); 43 | 44 | Map _$BridgeAmountInputConfigToJson( 45 | BridgeAmountInputConfig instance) => 46 | { 47 | 'token': instance.token, 48 | 'from': instance.from, 49 | 'to': instance.to, 50 | 'address': instance.address, 51 | 'minInput': instance.minInput, 52 | 'maxInput': instance.maxInput, 53 | 'destFee': instance.destFee, 54 | 'estimateFee': instance.estimateFee, 55 | 'xcmFee': instance.xcmFee, 56 | }; 57 | 58 | BridgeDestFeeData _$BridgeDestFeeDataFromJson(Map json) => 59 | BridgeDestFeeData( 60 | token: json['token'] as String, 61 | amount: json['amount'] as String, 62 | decimals: json['decimals'] as int, 63 | ); 64 | 65 | Map _$BridgeDestFeeDataToJson(BridgeDestFeeData instance) => 66 | { 67 | 'token': instance.token, 68 | 'amount': instance.amount, 69 | 'decimals': instance.decimals, 70 | }; 71 | -------------------------------------------------------------------------------- /lib/service/index.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:polkawallet_sdk/api/api.dart'; 4 | import 'package:polkawallet_sdk/service/account.dart'; 5 | import 'package:polkawallet_sdk/service/assets.dart'; 6 | import 'package:polkawallet_sdk/service/bridge.dart'; 7 | import 'package:polkawallet_sdk/service/eth/index.dart'; 8 | import 'package:polkawallet_sdk/service/gov.dart'; 9 | import 'package:polkawallet_sdk/service/gov2.dart'; 10 | import 'package:polkawallet_sdk/service/keyring.dart'; 11 | import 'package:polkawallet_sdk/service/parachain.dart'; 12 | import 'package:polkawallet_sdk/service/recovery.dart'; 13 | import 'package:polkawallet_sdk/service/setting.dart'; 14 | import 'package:polkawallet_sdk/service/staking.dart'; 15 | import 'package:polkawallet_sdk/service/tx.dart'; 16 | import 'package:polkawallet_sdk/service/uos.dart'; 17 | import 'package:polkawallet_sdk/service/walletConnect.dart'; 18 | import 'package:polkawallet_sdk/service/webViewRunner.dart'; 19 | import 'package:polkawallet_sdk/storage/keyring.dart'; 20 | 21 | /// The service calling JavaScript API of `polkadot-js/api` directly 22 | /// through [WebViewRunner], providing APIs for [PolkawalletApi]. 23 | class SubstrateService { 24 | late ServiceKeyring keyring; 25 | late ServiceSetting setting; 26 | late ServiceAccount account; 27 | late ServiceTx tx; 28 | 29 | late ServiceStaking staking; 30 | late ServiceGov gov; 31 | late ServiceGov2 gov2; 32 | late ServiceParachain parachain; 33 | late ServiceAssets assets; 34 | late ServiceBridge bridge; 35 | late ServiceUOS uos; 36 | late ServiceRecovery recovery; 37 | 38 | late ServiceWalletConnect walletConnect; 39 | late ServiceEth eth; 40 | 41 | WebViewRunner? _web; 42 | 43 | WebViewRunner? get webView => _web; 44 | 45 | Future init( 46 | Keyring keyringStorage, { 47 | WebViewRunner? webViewParam, 48 | Function? onInitiated, 49 | String? jsCode, 50 | Function? socketDisconnectedAction, 51 | }) async { 52 | keyring = ServiceKeyring(this); 53 | setting = ServiceSetting(this); 54 | account = ServiceAccount(this); 55 | tx = ServiceTx(this); 56 | staking = ServiceStaking(this); 57 | gov = ServiceGov(this); 58 | gov2 = ServiceGov2(this); 59 | parachain = ServiceParachain(this); 60 | assets = ServiceAssets(this); 61 | bridge = ServiceBridge(this); 62 | uos = ServiceUOS(this); 63 | recovery = ServiceRecovery(this); 64 | 65 | walletConnect = ServiceWalletConnect(this); 66 | eth = ServiceEth(this); 67 | 68 | _web = webViewParam ?? WebViewRunner(); 69 | await _web!.launch(onInitiated, 70 | jsCode: jsCode, socketDisconnectedAction: socketDisconnectedAction); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /lib/api/types/walletConnect/payloadData.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'payloadData.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | WCPayloadData _$WCPayloadDataFromJson(Map json) => 10 | WCPayloadData() 11 | ..topic = json['topic'] as String? 12 | ..chainId = json['chainId'] as String? 13 | ..payload = json['payload'] == null 14 | ? null 15 | : WCPayload.fromJson(json['payload'] as Map); 16 | 17 | Map _$WCPayloadDataToJson(WCPayloadData instance) => 18 | { 19 | 'topic': instance.topic, 20 | 'chainId': instance.chainId, 21 | 'payload': instance.payload?.toJson(), 22 | }; 23 | 24 | WCPayload _$WCPayloadFromJson(Map json) => WCPayload() 25 | ..id = json['id'] as int? 26 | ..method = json['method'] as String? 27 | ..params = json['params'] as List?; 28 | 29 | Map _$WCPayloadToJson(WCPayload instance) => { 30 | 'id': instance.id, 31 | 'method': instance.method, 32 | 'params': instance.params, 33 | }; 34 | 35 | WCCallRequestData _$WCCallRequestDataFromJson(Map json) => 36 | WCCallRequestData() 37 | ..event = json['event'] as String? 38 | ..topic = json['topic'] as String? 39 | ..id = json['id'] as int? 40 | ..params = (json['params'] as List?) 41 | ?.map((e) => 42 | WCCallRequestParamItem.fromJson(e.cast())) 43 | .toList(); 44 | 45 | Map _$WCCallRequestDataToJson(WCCallRequestData instance) => 46 | { 47 | 'event': instance.event, 48 | 'topic': instance.topic, 49 | 'id': instance.id, 50 | 'params': instance.params, 51 | }; 52 | 53 | WCCallRequestParamItem _$WCCallRequestParamItemFromJson( 54 | Map json) => 55 | WCCallRequestParamItem() 56 | ..label = json['label'] as String? 57 | ..value = json['value']; 58 | 59 | Map _$WCCallRequestParamItemToJson( 60 | WCCallRequestParamItem instance) => 61 | { 62 | 'label': instance.label, 63 | 'value': instance.value, 64 | }; 65 | 66 | WCCallRequestResult _$WCCallRequestResultFromJson(Map json) => 67 | WCCallRequestResult() 68 | ..result = json['result'] as String? 69 | ..error = json['error'] as String?; 70 | 71 | Map _$WCCallRequestResultToJson( 72 | WCCallRequestResult instance) => 73 | { 74 | 'result': instance.result, 75 | 'error': instance.error, 76 | }; 77 | -------------------------------------------------------------------------------- /lib/polkawallet_sdk.dart: -------------------------------------------------------------------------------- 1 | library polkawallet_sdk; 2 | 3 | import 'dart:async'; 4 | import 'dart:convert'; 5 | 6 | import 'package:http/http.dart'; 7 | import 'package:polkawallet_sdk/api/api.dart'; 8 | import 'package:polkawallet_sdk/service/index.dart'; 9 | import 'package:polkawallet_sdk/service/webViewRunner.dart'; 10 | import 'package:polkawallet_sdk/storage/keyring.dart'; 11 | import 'package:polkawallet_sdk/storage/keyringEVM.dart'; 12 | 13 | /// SDK launchs a hidden webView to run polkadot.js/api for interacting 14 | /// with the substrate-based block-chain network. 15 | class WalletSDK { 16 | late PolkawalletApi api; 17 | // late ApiEthers ethers; 18 | 19 | List _blackList = []; 20 | 21 | get blackList => _blackList; 22 | 23 | final _service = SubstrateService(); 24 | 25 | /// webView instance, this is the only instance of FlutterWebViewPlugin 26 | /// in App, we need to get it and reuse in other sdk. 27 | WebViewRunner? get webView => _service.webView; 28 | 29 | /// param [jsCode] is customized js code of parachain, 30 | /// the api works without [jsCode] param in Kusama/Polkadot. 31 | Future init( 32 | Keyring keyring, { 33 | KeyringEVM? keyringEVM, 34 | WebViewRunner? webView, 35 | String? jsCode, 36 | Function? socketDisconnectedAction, 37 | bool isEVM = false, 38 | }) async { 39 | final c = Completer(); 40 | 41 | await _service.init( 42 | keyring, 43 | webViewParam: webView, 44 | jsCode: jsCode, 45 | socketDisconnectedAction: socketDisconnectedAction, 46 | onInitiated: () { 47 | // inject keyPairs after webView launched 48 | _service.keyring.injectKeyPairsToWebView(keyring); 49 | // and initiate pubKeyIconsMap 50 | api.keyring.updatePubKeyIconsMap(keyring); 51 | 52 | if (keyringEVM != null) { 53 | _service.eth.keyring.injectKeyPairsToWebView(keyringEVM); 54 | api.eth.account.updateAddressIconsMap(keyringEVM); 55 | } 56 | 57 | _updateBlackList(); 58 | 59 | if (!c.isCompleted) { 60 | c.complete(); 61 | } 62 | }, 63 | ); 64 | 65 | api = PolkawalletApi(_service); 66 | // ethers = ApiEthers(_service); 67 | return c.future; 68 | } 69 | 70 | Future _updateBlackList() async { 71 | try { 72 | Response res = 73 | await get(Uri.parse('https://polkadot.js.org/phishing/address.json')); 74 | if (res.body.isNotEmpty) { 75 | final data = jsonDecode(res.body) as Map; 76 | final List list = []; 77 | data.values.forEach((e) { 78 | list.addAll(List.from(e)); 79 | }); 80 | final pubKeys = await api.account.decodeAddress(list); 81 | if (pubKeys != null) { 82 | _blackList = List.from(pubKeys.keys.toList()); 83 | } 84 | } 85 | } catch (err) { 86 | print(err); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /lib/api/types/balanceData.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'balanceData.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | BalanceData _$BalanceDataFromJson(Map json) => BalanceData() 10 | ..accountId = json['accountId'] as String? 11 | ..accountNonce = json['accountNonce'] 12 | ..availableBalance = json['availableBalance'] 13 | ..freeBalance = json['freeBalance'] 14 | ..frozenFee = json['frozenFee'] 15 | ..frozenMisc = json['frozenMisc'] 16 | ..isVesting = json['isVesting'] as bool? 17 | ..lockedBalance = json['lockedBalance'] 18 | ..lockedBreakdown = (json['lockedBreakdown'] as List?) 19 | ?.map((e) => BalanceBreakdownData.fromJson(e as Map)) 20 | .toList() 21 | ..reservedBalance = json['reservedBalance'] 22 | ..vestedBalance = json['vestedBalance'] 23 | ..vestedClaimable = json['vestedClaimable'] 24 | ..vestingEndBlock = json['vestingEndBlock'] 25 | ..vestingLocked = json['vestingLocked'] 26 | ..vestingPerBlock = json['vestingPerBlock'] 27 | ..vestingTotal = json['vestingTotal'] 28 | ..votingBalance = json['votingBalance'] 29 | ..isFromCache = json['isFromCache'] as bool?; 30 | 31 | Map _$BalanceDataToJson(BalanceData instance) => 32 | { 33 | 'accountId': instance.accountId, 34 | 'accountNonce': instance.accountNonce, 35 | 'availableBalance': instance.availableBalance, 36 | 'freeBalance': instance.freeBalance, 37 | 'frozenFee': instance.frozenFee, 38 | 'frozenMisc': instance.frozenMisc, 39 | 'isVesting': instance.isVesting, 40 | 'lockedBalance': instance.lockedBalance, 41 | 'lockedBreakdown': 42 | instance.lockedBreakdown?.map((e) => e.toJson()).toList(), 43 | 'reservedBalance': instance.reservedBalance, 44 | 'vestedBalance': instance.vestedBalance, 45 | 'vestedClaimable': instance.vestedClaimable, 46 | 'vestingEndBlock': instance.vestingEndBlock, 47 | 'vestingLocked': instance.vestingLocked, 48 | 'vestingPerBlock': instance.vestingPerBlock, 49 | 'vestingTotal': instance.vestingTotal, 50 | 'votingBalance': instance.votingBalance, 51 | 'isFromCache': instance.isFromCache, 52 | }; 53 | 54 | BalanceBreakdownData _$BalanceBreakdownDataFromJson( 55 | Map json) => 56 | BalanceBreakdownData() 57 | ..id = json['id'] as String? 58 | ..amount = json['amount'] 59 | ..reasons = json['reasons'] as String? 60 | ..use = json['use'] as String?; 61 | 62 | Map _$BalanceBreakdownDataToJson( 63 | BalanceBreakdownData instance) => 64 | { 65 | 'id': instance.id, 66 | 'amount': instance.amount, 67 | 'reasons': instance.reasons, 68 | 'use': instance.use, 69 | }; 70 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: polkawallet_sdk_example 2 | description: polkawallet_sdk_example. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 0.0.1+11 19 | 20 | environment: 21 | sdk: ">=2.12.0 <3.0.0" 22 | 23 | dependencies: 24 | flutter: 25 | sdk: flutter 26 | 27 | 28 | dev_dependencies: 29 | polkawallet_sdk: 30 | path: ../ 31 | 32 | # For information on the generic Dart part of this file, see the 33 | # following page: https://dart.dev/tools/pub/pubspec 34 | 35 | # The following section is specific to Flutter. 36 | flutter: 37 | 38 | # The following line ensures that the Material Icons font is 39 | # included with your application, so that you can use the icons in 40 | # the material Icons class. 41 | uses-material-design: true 42 | 43 | # To add assets to your application, add an assets section, like this: 44 | # assets: 45 | # - images/a_dot_burr.jpeg 46 | # - images/a_dot_ham.jpeg 47 | 48 | # An image asset can refer to one or more resolution-specific "variants", see 49 | # https://flutter.dev/assets-and-images/#resolution-aware. 50 | 51 | # For details regarding adding assets from package dependencies, see 52 | # https://flutter.dev/assets-and-images/#from-packages 53 | 54 | # To add custom fonts to your application, add a fonts section here, 55 | # in this "flutter" section. Each entry in this list should have a 56 | # "family" key with the font family name, and a "fonts" key with a 57 | # list giving the asset and other descriptors for the font. For 58 | # example: 59 | # fonts: 60 | # - family: Schyler 61 | # fonts: 62 | # - asset: fonts/Schyler-Regular.ttf 63 | # - asset: fonts/Schyler-Italic.ttf 64 | # style: italic 65 | # - family: Trajan Pro 66 | # fonts: 67 | # - asset: fonts/TrajanPro.ttf 68 | # - asset: fonts/TrajanPro_Bold.ttf 69 | # weight: 700 70 | # 71 | # For details regarding fonts from package dependencies, 72 | # see https://flutter.dev/custom-fonts/#from-packages 73 | -------------------------------------------------------------------------------- /lib/api/apiAccount.dart: -------------------------------------------------------------------------------- 1 | import 'package:polkawallet_sdk/api/api.dart'; 2 | import 'package:polkawallet_sdk/api/types/balanceData.dart'; 3 | import 'package:polkawallet_sdk/service/account.dart'; 4 | 5 | class ApiAccount { 6 | ApiAccount(this.apiRoot, this.service); 7 | 8 | final PolkawalletApi apiRoot; 9 | final ServiceAccount service; 10 | 11 | /// encode addresses to publicKeys 12 | Future encodeAddress(List pubKeys) async { 13 | final int? ss58 = apiRoot.connectedNode!.ss58; 14 | final Map? res = await service.encodeAddress(pubKeys, [ss58]); 15 | if (res != null) { 16 | return res[ss58.toString()]; 17 | } 18 | return null; 19 | } 20 | 21 | /// decode addresses to publicKeys 22 | Future decodeAddress(List addresses) async { 23 | return service.decodeAddress(addresses); 24 | } 25 | 26 | /// check address matches ss58Format 27 | Future checkAddressFormat(String address, int ss58) async { 28 | return service.checkAddressFormat(address, ss58); 29 | } 30 | 31 | /// query balance 32 | Future queryBalance(String? address) async { 33 | final res = await service.queryBalance(address); 34 | return res != null 35 | ? BalanceData.fromJson(res as Map) 36 | : null; 37 | } 38 | 39 | /// subscribe balance 40 | /// @return [String] msgChannel, call unsubscribeMessage(msgChannel) to unsub. 41 | Future subscribeBalance( 42 | String? address, 43 | Function(BalanceData) onUpdate, 44 | ) async { 45 | final msgChannel = 'Balance'; 46 | final code = 'account.getBalance(api, "$address", "$msgChannel")'; 47 | await apiRoot.service.webView!.subscribeMessage( 48 | code, msgChannel, (data) => onUpdate(BalanceData.fromJson(data))); 49 | return msgChannel; 50 | } 51 | 52 | /// unsubscribe balance 53 | void unsubscribeBalance() { 54 | final msgChannel = 'Balance'; 55 | apiRoot.unsubscribeMessage(msgChannel); 56 | } 57 | 58 | /// Get on-chain account info of addresses 59 | Future queryIndexInfo(List addresses) async { 60 | if (addresses.isEmpty) { 61 | return []; 62 | } 63 | 64 | return service.queryIndexInfo(addresses); 65 | } 66 | 67 | /// query address with account index 68 | Future queryAddressWithAccountIndex(String index) async { 69 | final res = await service.queryAddressWithAccountIndex( 70 | index, apiRoot.connectedNode!.ss58); 71 | if (res != null) { 72 | return res[0]; 73 | } 74 | return null; 75 | } 76 | 77 | /// Get icons of pubKeys 78 | /// return svg strings 79 | Future getPubKeyIcons(List keys) async { 80 | if (keys.length == 0) { 81 | return []; 82 | } 83 | return service.getPubKeyIcons(keys); 84 | } 85 | 86 | /// Get icons of addresses 87 | /// return svg strings 88 | Future getAddressIcons(List addresses) async { 89 | if (addresses.isEmpty) { 90 | return []; 91 | } 92 | return service.getAddressIcons(addresses); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /lib/api/types/walletConnect/pairingData.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'pairingData.g.dart'; 4 | 5 | @JsonSerializable(explicitToJson: true) 6 | class WCPairingData extends _WCPairingData { 7 | static WCPairingData fromJson(Map json) => 8 | _$WCPairingDataFromJson(json as Map); 9 | Map toJson() => _$WCPairingDataToJson(this); 10 | } 11 | 12 | abstract class _WCPairingData { 13 | int? id; 14 | WCPairingParamsData? params; 15 | } 16 | 17 | @JsonSerializable(explicitToJson: true) 18 | class WCPairingParamsData extends _WCPairingParamsData { 19 | static WCPairingParamsData fromJson(Map json) => 20 | _$WCPairingParamsDataFromJson(json as Map); 21 | Map toJson() => _$WCPairingParamsDataToJson(this); 22 | } 23 | 24 | abstract class _WCPairingParamsData { 25 | int? id; 26 | int? expiry; 27 | List? relays; 28 | WCProposerInfo? proposer; 29 | Map? requiredNamespaces; 30 | String? pairingTopic; 31 | } 32 | 33 | @JsonSerializable(explicitToJson: true) 34 | class WCRelayProtocol extends _WCRelayProtocol { 35 | static WCRelayProtocol fromJson(Map json) => 36 | _$WCRelayProtocolFromJson(json as Map); 37 | Map toJson() => _$WCRelayProtocolToJson(this); 38 | } 39 | 40 | abstract class _WCRelayProtocol { 41 | String? protocol; 42 | String? data; 43 | } 44 | 45 | @JsonSerializable(explicitToJson: true) 46 | class WCProposerInfo extends _WCProposerInfo { 47 | static WCProposerInfo fromJson(Map json) => 48 | _$WCProposerInfoFromJson(json as Map); 49 | Map toJson() => _$WCProposerInfoToJson(this); 50 | } 51 | 52 | abstract class _WCProposerInfo { 53 | String? publicKey; 54 | WCProposerMeta? metadata; 55 | } 56 | 57 | @JsonSerializable() 58 | class WCProposerMeta extends _WCProposerMeta { 59 | static WCProposerMeta fromJson(Map json) => 60 | _$WCProposerMetaFromJson(json as Map); 61 | Map toJson() => _$WCProposerMetaToJson(this); 62 | } 63 | 64 | abstract class _WCProposerMeta { 65 | String? name; 66 | String? description; 67 | String? url; 68 | List? icons; 69 | } 70 | 71 | @JsonSerializable() 72 | class WCSessionDataV2 extends _WCSessionDataV2 { 73 | static WCSessionDataV2 fromJson(Map json) => 74 | _$WCSessionDataV2FromJson(json as Map); 75 | Map toJson() => _$WCSessionDataV2ToJson(this); 76 | } 77 | 78 | abstract class _WCSessionDataV2 { 79 | String? topic; 80 | WCProposerMeta? peerMeta; 81 | Map? namespaces; 82 | int? expiry; 83 | } 84 | 85 | @JsonSerializable() 86 | class WCPermissionNamespaces extends _WCPermissionNamespaces { 87 | static WCPermissionNamespaces fromJson(Map json) => 88 | _$WCPermissionNamespacesFromJson(json as Map); 89 | Map toJson() => _$WCPermissionNamespacesToJson(this); 90 | } 91 | 92 | abstract class _WCPermissionNamespaces { 93 | List? chains; 94 | List? accounts; 95 | List? methods; 96 | List? events; 97 | } 98 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | --------------------------------------------------------------------------------