Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## 3.3.0-beta05
## 3.3.0-beta06

- One-Click Auth + SIWE implementation
- Coinbase Wallet dependency update
Expand Down
2 changes: 1 addition & 1 deletion example/android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
versionName=3.3.0
versionCode=66
versionCode=67
12 changes: 6 additions & 6 deletions example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 66;
CURRENT_PROJECT_VERSION = 67;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = W5R8AG9K22;
ENABLE_BITCODE = NO;
Expand All @@ -496,7 +496,7 @@
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 66;
CURRENT_PROJECT_VERSION = 67;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.web3modal.flutterExample.RunnerTests;
Expand All @@ -514,7 +514,7 @@
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 66;
CURRENT_PROJECT_VERSION = 67;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.web3modal.flutterExample.RunnerTests;
Expand All @@ -530,7 +530,7 @@
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 66;
CURRENT_PROJECT_VERSION = 67;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.web3modal.flutterExample.RunnerTests;
Expand Down Expand Up @@ -655,7 +655,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 66;
CURRENT_PROJECT_VERSION = 67;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = W5R8AG9K22;
ENABLE_BITCODE = NO;
Expand Down Expand Up @@ -686,7 +686,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 66;
CURRENT_PROJECT_VERSION = 67;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = W5R8AG9K22;
ENABLE_BITCODE = NO;
Expand Down
2 changes: 1 addition & 1 deletion example/ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>66</string>
<string>67</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationQueriesSchemes</key>
Expand Down
6 changes: 3 additions & 3 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,10 @@ packages:
dependency: transitive
description:
name: coinbase_wallet_sdk
sha256: e18bd5351939aacda75c0b525aa9167b945f1206040ec254f971afe96dfd98b0
sha256: "4a309b22d1d8647ab4381ac075921dba211ac642f58b2ca06c0c1fb8f58973da"
url: "https://pub.dev"
source: hosted
version: "1.0.8"
version: "1.0.9"
collection:
dependency: transitive
description:
Expand Down Expand Up @@ -1131,7 +1131,7 @@ packages:
path: ".."
relative: true
source: path
version: "3.3.0-beta05"
version: "3.3.0-beta06"
web_socket_channel:
dependency: transitive
description:
Expand Down
8 changes: 7 additions & 1 deletion lib/pages/approve_magic_request_page.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:web3modal_flutter/constants/key_constants.dart';
import 'package:web3modal_flutter/services/magic_service/magic_service_singleton.dart';
import 'package:web3modal_flutter/widgets/miscellaneous/responsive_container.dart';
import 'package:web3modal_flutter/widgets/navigation/navbar.dart';

class ApproveTransactionPage extends StatefulWidget {
Expand All @@ -22,7 +23,12 @@ class _ApproveTransactionPageState extends State<ApproveTransactionPage> {
noClose: true,
safeAreaLeft: true,
safeAreaRight: true,
body: magicService.instance.webview,
body: ConstrainedBox(
constraints: BoxConstraints(
maxHeight: ResponsiveData.maxHeightOf(context),
),
child: magicService.instance.webview,
),
);
}
}
3 changes: 2 additions & 1 deletion lib/pages/approve_siwe.dart
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,12 @@ class _ApproveSIWEPageState extends State<ApproveSIWEPage> {
debugPrint('[$runtimeType] _handleError $error');
String chainId = _service!.selectedChain?.chainId ?? '1';
analyticsService.instance.sendEvent(SiweAuthError(network: chainId));
setState(() => _waitingSign = false);
toastUtils.instance.show(ToastMessage(
type: ToastType.error,
text: error ?? 'Something went wrong.',
));
if (!mounted) return;
setState(() => _waitingSign = false);
}

void _cancelSIWE() async {
Expand Down
156 changes: 110 additions & 46 deletions lib/services/blockchain_service/blockchain_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,72 +6,136 @@ import 'package:web3modal_flutter/constants/string_constants.dart';
import 'package:web3modal_flutter/constants/url_constants.dart';
import 'package:web3modal_flutter/services/blockchain_service/models/blockchain_identity.dart';
import 'package:web3modal_flutter/services/blockchain_service/i_blockchain_service.dart';
import 'package:web3modal_flutter/services/logger_service/logger_service_singleton.dart';

class BlockChainService implements IBlockChainService {
late final ICore _core;
late final String _baseUrl;
late final String _clientId;

BlockChainService({required ICore core}) : _core = core;

class BlockChainService extends IBlockChainService {
//
@override
final String projectId;
Future<void> init() async {
_baseUrl = '${UrlConstants.blockChainService}/v1';
_clientId = await _core.crypto.getClientId();
}

final IWeb3App _web3app;
Map<String, String> get _requiredParams => {
'projectId': _core.projectId,
'clientId': _clientId,
};

BlockChainService({
required this.projectId,
required IWeb3App web3app,
}) : _web3app = web3app;
Map<String, String> get _requiredHeaders => {
'x-sdk-type': StringConstants.X_SDK_TYPE,
'x-sdk-version': 'flutter-${StringConstants.X_SDK_VERSION}',
};

@override
Future<BlockchainIdentity> getIdentity(String address, int chainId) async {
final scope = '${StringConstants.namespace}:$chainId';
final clientId = await _web3app.core.crypto.getClientId();
final uri = Uri.parse(
'${UrlConstants.blockChainService}/v1/identity/$address',
Future<BlockchainIdentity> getIdentity(String address) async {
try {
final uri = Uri.parse('$_baseUrl/identity/$address');
final queryParams = {..._requiredParams};
final response = await http.get(
uri.replace(queryParameters: queryParams),
headers: _requiredHeaders,
);
if (response.statusCode == 200) {
return BlockchainIdentity.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to load avatar');
}
} catch (e) {
loggerService.instance.e('[$runtimeType] getIdentity: $e');
rethrow;
}
}

@override
Future<dynamic> getRpcRequest({
required String method,
required List<dynamic> params,
required String chain,
}) async {
final bool isChainId = NamespaceUtils.isValidChainId(chain);
if (!isChainId) {
throw Errors.getSdkError(
Errors.UNSUPPORTED_CHAINS,
context: '[$runtimeType] chain should be CAIP-2 valid',
);
}
final uri = Uri.parse(_baseUrl);
final queryParams = {..._requiredParams, 'chainId': chain};
final response = await http.post(
uri.replace(queryParameters: queryParams),
headers: {
..._requiredHeaders,
'Content-Type': 'application/json',
},
body: jsonEncode({
'jsonrpc': '2.0',
'method': method,
'params': params,
'chainId': chain.split(':').last,
}),
);
final queryParams = {
'chainId': scope,
'projectId': projectId,
'clientId': clientId,
};
final response = await http.get(uri.replace(queryParameters: queryParams));
if (response.statusCode == 200) {
return BlockchainIdentity.fromJson(jsonDecode(response.body));
if (response.statusCode == 200 && response.body.isNotEmpty) {
try {
final result = _parseRpcResultAs<String>(response.body);
final amount = EtherAmount.fromBigInt(EtherUnit.wei, hexToInt(result));
return amount.getValueInUnit(EtherUnit.ether);
} catch (e) {
rethrow;
}
} else {
throw Exception('Failed to load avatar');
throw Exception('Failed to get request $method');
}
}

T _parseRpcResultAs<T>(String body) {
final result = Map<String, dynamic>.from({
...jsonDecode(body),
'id': -1,
});
final jsonResponse = JsonRpcResponse.fromJson(result);
if (jsonResponse.result != null) {
return jsonResponse.result;
}
throw jsonResponse.error!;
}

// TODO to be implemented
// @override
// Future<JsonRpcResponse?> getBalance(String chainId, String address) async {
// // final client = Web3Client(rpcUrl, Client());
// // final amount = await client.getBalance(EthereumAddress.fromHex(address));
// // return amount.getValueInUnit(EtherUnit.ether);
// final scope = '${StringConstants.namespace}:$chainId';
// final clientId = await _web3app.core.crypto.getClientId();
// final uri = Uri.parse('${UrlConstants.blockChainService}/v1');
// Future<double?> getBalance(
// String address,
// String currency, {
// String? chain,
// String? forceUpdate,
// }) async {
// final uri = Uri.parse('$_baseUrl/account/$address/balance');
// final queryParams = {
// 'chainId': scope,
// 'projectId': projectId,
// 'clientId': clientId,
// ..._requiredParams,
// 'currency': currency,
// if (chain != null) 'chainId': chain,
// if (forceUpdate != null) 'forceUpdate': forceUpdate,
// };
// // "chainId=eip155%3A1&projectId=cad4956f31a5e40a00b62865b030c6f8&clientId=did%3Akey%3Az6MkgNA9sezpYrpiJGSkkQwUQSqoEWSDsDFZifbu6tYbu…"
// final response = await http.post(
// final response = await http.get(
// uri.replace(queryParameters: queryParams),
// headers: {
// ...coreUtils.instance.getAPIHeaders(projectId),
// 'Content-Type': 'application/json',
// ..._requiredHeaders,
// // 'chain': chainId,
// // 'forceUpdate': string
// // 'Content-Type': 'application/json',
// },
// body: jsonEncode({
// 'jsonrpc': '2.0',
// 'method': 'eth_getBalance',
// 'params': [address, 'latest'],
// 'chainId': 1
// }),
// // body: jsonEncode({
// // 'jsonrpc': '2.0',
// // 'method': 'eth_getBalance',
// // 'params': [address, 'latest'],
// // 'chainId': 1
// // }),
// );
// print(response.body);
// _core.logger.i('[$runtimeType] getBalance $address: ${response.body}');
// if (response.statusCode == 200) {
// final result = JsonRpcResponse.fromJson(jsonDecode(response.body));
// final bytes = hex.decode(result.result.toString().replaceFirst('0x', ''));
// // "{"jsonrpc":"2.0","id":"","result":"0x0"}"
// } else {
// throw Exception('Failed to load balance');
// }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:web3modal_flutter/services/blockchain_service/i_blockchain_service.dart';

class BlockChainServiceSingleton {
IBlockChainService? instance;
late IBlockChainService instance;
}

final blockchainService = BlockChainServiceSingleton();
15 changes: 7 additions & 8 deletions lib/services/blockchain_service/i_blockchain_service.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import 'package:web3modal_flutter/services/blockchain_service/models/blockchain_identity.dart';

abstract class IBlockChainService {
/// The project ID used when querying the API.
String get projectId;
Future<void> init();

/// Gets the name and avatar of a provided address on the given chain
Future<BlockchainIdentity> getIdentity(String address, int chainId);
Future<BlockchainIdentity> getIdentity(String address);

// Future<JsonRpcResponse?> getBalance(String chainId, String address);

// Future<String> fetchEnsName(String rpcUrl, String address);

// Future<String> fetchEnsAvatar(String rpcUrl, String address);
Future<dynamic> getRpcRequest({
required String method,
required List<dynamic> params,
required String chain,
});
}
16 changes: 9 additions & 7 deletions lib/services/coinbase_service/coinbase_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,14 @@ class CoinbaseService implements ICoinbaseService {
Event<CoinbaseResponseEvent> get onCoinbaseResponse =>
Event<CoinbaseResponseEvent>();

final IWeb3App _web3app;
late final PairingMetadata _metadata;
late bool _enabled;
late W3MWalletInfo _walletData;

CoinbaseService({required IWeb3App web3app, bool enabled = false})
: _web3app = web3app,
CoinbaseService({
required PairingMetadata metadata,
bool enabled = false,
}) : _metadata = metadata,
_enabled = enabled;

@override
Expand All @@ -97,8 +99,8 @@ class CoinbaseService implements ICoinbaseService {
final imageId = defaultWalletData.listing.imageId;
_iconImage = explorerService.instance.getWalletImageUrl(imageId);

final universal = _web3app.metadata.redirect?.universal ?? '';
final nativeLink = _web3app.metadata.redirect?.native ?? '';
final universal = _metadata.redirect?.universal ?? '';
final nativeLink = _metadata.redirect?.native ?? '';
final walletLink = _walletData.listing.mobileLink ?? '';
if ((universal.isNotEmpty && nativeLink.isNotEmpty) ||
walletLink.isNotEmpty) {
Expand Down Expand Up @@ -162,7 +164,7 @@ class CoinbaseService implements ICoinbaseService {
publicKey: await peerPublicKey,
),
self: ConnectionMetadata(
metadata: _web3app.metadata,
metadata: _metadata,
publicKey: await ownPublicKey,
),
);
Expand Down Expand Up @@ -209,7 +211,7 @@ class CoinbaseService implements ICoinbaseService {
publicKey: await peerPublicKey,
),
self: ConnectionMetadata(
metadata: _web3app.metadata,
metadata: _metadata,
publicKey: await ownPublicKey,
),
);
Expand Down
Loading