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
11 changes: 11 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = tab

[*.{dart,yml,yaml}]
indent_style = space
indent_size = 2
21 changes: 21 additions & 0 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Bug report
description: Report a reproducible problem
title: "[Bug]: "
body:
- type: textarea
id: behavior
attributes:
label: Expected and actual behavior
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: Minimal reproduction
description: Include package/runtime versions, platform, and steps. Remove keys, credentials, cookies and personal data.
validations:
required: true
- type: textarea
id: logs
attributes:
label: Sanitized error codes and logs
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Private vulnerability report
url: https://github.com/bchainhub/flutter_connect/security/advisories/new
about: Report security vulnerabilities privately.
14 changes: 14 additions & 0 deletions .github/ISSUE_TEMPLATE/feature.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Feature request
description: Suggest an improvement
title: "[Feature]: "
body:
- type: textarea
id: problem
attributes:
label: Problem and proposed behavior
validations:
required: true
- type: textarea
id: compatibility
attributes:
label: Compatibility and security considerations
7 changes: 7 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## Change

Describe the problem and resulting behavior.

## Validation

List relevant tests and compatibility effects.
53 changes: 53 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: CI
on:
push:
branches: [main, master]
pull_request:
workflow_call:
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- run: flutter pub get
- run: dart format --output=none --set-exit-if-changed lib test example/lib example/test
- run: flutter analyze
- run: flutter test
- run: flutter test
working-directory: example
- run: flutter pub publish --dry-run
android:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- run: flutter pub get
- run: flutter build apk --debug
working-directory: example
ios:
runs-on: macos-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- run: flutter pub get
- run: flutter build ios --simulator --debug
working-directory: example
32 changes: 32 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Release
on:
push:
tags: ['[0-9]*.[0-9]*.[0-9]*']
permissions:
contents: read
jobs:
validate:
uses: ./.github/workflows/ci.yml
tag:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Verify version
run: |
version=$(sed -n 's/^version: //p' pubspec.yaml)
test "$GITHUB_REF_NAME" = "$version"
publish:
needs: [validate, tag]
permissions:
id-token: write
uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1
release:
needs: publish
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- run: gh release create "$GITHUB_REF_NAME" --verify-tag --generate-notes
env:
GH_TOKEN: ${{ github.token }}
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.dart_tool/
.flutter-plugins-dependencies
build/
.DS_Store
# Dependency lockfiles
*.lock
package-lock.json
npm-shrinkwrap.json
pnpm-lock.yaml
bun.lockb
Package.resolved

# Generated protocol artifacts
/vectors/
/vendor/
/.connect-sdk/
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Changelog

## 0.1.0

Initial Connect v1 implementation, shared conformance vectors, security tests, examples and release automation.

- Add named chain presets, wallet adapters and extensible server verifiers for all fourteen requested chains, plus Bitcoin legacy and XRP Ed25519. Expand shared fixtures and live cross-language authentication tests.

- Use connect.js for browser-only authentication and wallet adapters. better-connect independently owns HTTP endpoints, backend state transitions and Better Auth sessions.

- Rename the browser wallet entry to connect.js/wallet; add brand-neutral discovery, Solana and CIP-30 adapters, TronLink-style signing and native wallet bridges. Add shared Core Blockchain Ed448/ICAN helpers and a future-wallet bridge with mainnet/Devin support.
19 changes: 19 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
CORE License

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"),
to to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

All distribution of the Covered Software in Source Code Form, including any
Modifications and/or Contributions must be disclosed and publicly available.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE TO ANY CLAIM, DAMAGES OR
OTHER LIABILITIES, WHETHER IN AN ACTION OF A CONTRACT, TORT, OR OTHERWISE,
ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE, OR
OTHER DEALINGS IN THE SOFTWARE.
78 changes: 77 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,78 @@
# flutter_connect
Connect Protocol

Flutter wallet library for Connect v1. Handles full `connect://` links and QR text for any dapp; validates the challenge, asks the user to approve signing, and returns an encrypted proof through Bluetooth or another channel. Better Auth is optional. See [nearby integration](doc/NEARBY.md).

```yaml
dependencies:
flutter_connect: ^0.1.0
```

```dart
final connect = ConnectClient(
accountProvider: myWalletAccountProvider,
);
connect.requests.listen((request) {
// Present domain/origin, account, network, profile and expiry in trusted UI.
});
final request = await connect.resolve(scannedQrText);
// From an explicit Approve button only:
await request.approve(request.compatibleAccounts.first);
```

A `WalletAccountProvider` returns `WalletAccount` objects with a `SigningSelection` and `sign(Uint8List canonicalPayload)`. The selection contains `WalletIdentity(namespace, reference, address)`, profile and COSE algorithm (or null). Signatures are returned as `WalletSignature`; private keys remain inside the account implementation. `ConnectRequest` exposes immutable `challenge`, `compatibleAccounts`, `state`, `approve`, `reject` and `cancel`.

```dart
class XcbAccount implements WalletAccount {
@override
final SigningSelection selection;
final Future<WalletSignature> Function(Uint8List) nativeSign;
XcbAccount(String address, this.nativeSign)
: selection = SigningSelection(
account: WalletIdentity(namespace: 'core', reference: '1', address: address),
profile: 'xcb-ed448', alg: coseEd448);
@override
Future<WalletSignature> sign(Uint8List payload) => nativeSign(payload);
}
```

The native XCB signer must use pure Ed448 over the supplied bytes, without extra hashing/prefixing, and return a 57-byte public key plus 114-byte signature as lowercase hex. An Ethereum adapter selects `eip155`, decimal chain reference, an EIP-55 address, `ethereum-siwe`, and null algorithm; it passes the canonical bytes to EIP-191 personal_sign. Bitcoin selects `bitcoin-bip322-p2wpkh` with its BIP122 reference and signs using BIP-322 simple. The host implements wallet signing; the SDK encrypts responses without receiving private signing keys.

```dart
WidgetsFlutterBinding.ensureInitialized();
final links = ConnectLinks(client: connect, onError: showSafeError);
await links.start(); // cold-start and running-app links
// On owner disposal: await links.dispose(); await connect.dispose();
```

Register Android/iOS schemes using [platform setup](doc/PLATFORMS.md); the checked-in [example](example) includes the required manifest/plist entries and an ephemeral Ed25519 account with a native confirmation screen. QR scanners, clipboard controls and navigation remain host-app choices. For direct invocation use `resolveTarget(ConnectTarget(origin, requestId))`. HTTPS/Universal/App Links resolve to identical canonical bytes. Same-device login uses the same protocol and manual return to the browser; arbitrary callback URLs are rejected.

A full handoff needs no `ConnectNetwork`. Short-URI HTTP compatibility requires explicitly passing `network: HttpsNetwork()`. `responseReady` means the proof is ready to return, not that portal sign-in succeeded.

```dart
// After showing and confirming request.challenge.origin:
final peripheral = ConnectBluetoothPeripheral(
handoff: request.handoff!, onError: showSafeError,
);
await peripheral.start();
// From an explicit signing approval:
await request.approve(request.compatibleAccounts.first);
peripheral.publish(request.response!);
// On cancellation/disposal: await peripheral.stop();
```


Named presets cover Core Blockchain, Ethereum, Polygon, Base, Bitcoin, Solana, BNB Smart Chain, TRON, Monero, Stellar, Litecoin, XRP, Zcash and Cardano. Use `ChainWalletAccount(chain: ConnectChains.solana, address: address, sign: callback)` to avoid configuring low-level profiles. See [supported addresses and wallet methods](doc/CHAINS.md). Full details are in the [protocol](doc/PROTOCOL.md) and [research notes](doc/IMPLEMENTATION.md).

```sh
flutter pub get
dart format --output=none --set-exit-if-changed lib test example/lib example/test
flutter analyze
flutter test
cd example && flutter test
# From the sibling better-connect checkout:
node scripts/flutter-interop.mjs
```

Shared vectors assert identical Dart/TypeScript messages. Dart Ed25519 signatures and an OpenSSL Ed448 host bridge also complete real Better Auth desktop sessions. The OpenSSL fixture requires OpenSSL 3 on the test host; it is not a mobile signing implementation. The standalone suite skips live-server tests unless the integration runner supplies its test endpoint.

See [release setup](doc/RELEASE.md). Licensed under the [CORE License](LICENSE).
5 changes: 5 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Security policy

Report vulnerabilities privately through this repository's GitHub Security Advisories. Do not post private keys, redemption credentials, session cookies or exploitable proof material in public issues. Version 0.1.x is the initial supported line.

See doc/PROTOCOL.md for the threat model, supported profiles and transport restrictions. This is a new protocol implementation with automated security tests; it has not received an independent security audit.
4 changes: 4 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
analyzer:
exclude:
- build/**
include: package:flutter_lints/flutter.yaml
Loading
Loading