Skip to content
Open
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
395 changes: 390 additions & 5 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ members = [
"btp",
"ql-codec",
"ql-common",
"ql-keyos",
"ql-api",
"ql-fsm",
"ql-rpc",
"ql-runtime",
Expand All @@ -27,5 +29,6 @@ btp = { path = "btp" }
ql-codec = { path = "ql-codec" }
ql-common = { path = "ql-common" }
ql-fsm = { path = "ql-fsm" }
ql-keyos = { path = "ql-keyos" }
ql-rpc = { path = "ql-rpc" }
ql-wire = { path = "ql-wire" }
22 changes: 22 additions & 0 deletions ql-api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "ql-api"
version = "0.1.0"
edition = "2021"
description = "KeyOS QLv2 RPC protocol"
license = "Proprietary"


[dependencies]
ql-codec = { workspace = true }
ql-keyos = { workspace = true, features = ["serde"] }
ql-rpc = { workspace = true }
bytes = { workspace = true }
ciborium = "0.2.2"
flutter_rust_bridge = { version = "=2.11.1", optional = true }
serde = { version = "1.0", features = ["derive"] }

[features]
frb = ["flutter_rust_bridge"]

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(frb_expand)'] }
65 changes: 65 additions & 0 deletions ql-api/src/app_store.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use ql_rpc::{Download, Request};

use crate::{Empty, Error};

// COMMON TYPES

rpc! {
#[derive(Copy)]
pub struct AppVersion(pub u32, pub u32, pub u32);
}

rpc! {
pub struct AppDetails {
pub name: String,
pub icon: String, // SVG?
pub developer_id: Vec<u8>,
pub app_id: Vec<u8>,
}
}

// APP ROUTES

// SERVICE ROUTES

service_routes! {
crate::service_id::APP_STORE => {
RequestListApps: Request = 1,
DownloadApp: Download = 2,
}
}

rpc! {
pub struct ListAppsResponse {
pub apps: Vec<AppDetails>,
}
}

impl Request for RequestListApps {
type Error = Error;
type Request = Empty;
type Response = ListAppsResponse;
}

rpc! {
pub struct DownloadAppParams {
pub version: Option<String>,
}
}

rpc! {
pub struct DownloadAppHeader {
pub version: String,
}
}

rpc! {
pub struct DownloadAppPartHeader {}
}

impl Download for DownloadApp {
type Error = Error;
type Request = DownloadAppParams;
type ResponseHeader = DownloadAppHeader;
type PartHeader = DownloadAppPartHeader;
}
172 changes: 172 additions & 0 deletions ql-api/src/backup.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
use ql_rpc::{Download, Request, Subscription, Upload};

use crate::{Empty, Error};

// COMMON TYPES

rpc! {
pub struct Shard(pub Vec<u8>);
}

rpc! {
pub struct SeedFingerprint(pub [u8; 32]);
}

// APP ROUTES

app_routes! {
crate::app_id::BACKUP => {
SubscribePassportMagicBackupEnabled: Subscription = 1,
SubscribeMagicBackupRestoreCompleted: Subscription = 2,
}
}

rpc! {
pub struct PassportMagicBackupEnabled {
pub enabled: bool,
pub seed_fingerprint: SeedFingerprint,
}
}

impl Subscription for SubscribePassportMagicBackupEnabled {
type Error = Error;
type Request = Empty;
type Event = PassportMagicBackupEnabled;
}

rpc! {
pub enum MagicBackupRestoreResult {
Success,
Error { error: String },
}
}

impl Subscription for SubscribeMagicBackupRestoreCompleted {
type Error = Error;
type Request = Empty;
type Event = MagicBackupRestoreResult;
}

// SERVICE ROUTES

service_routes! {
crate::service_id::BACKUP => {
RequestBackupShard: Request = 1,
RequestRestoreShard: Request = 2,
RequestPassportMagicBackupStatus: Request = 3,
UploadMagicBackup: Upload = 4,
DownloadMagicBackup: Download = 5,
}
}

rpc! {
pub struct BackupShardParams {
pub shard: Shard,
}
}

rpc! {
pub enum BackupShardResponse {
Success,
Error { error: String },
}
}

impl Request for RequestBackupShard {
type Error = Error;
type Request = BackupShardParams;
type Response = BackupShardResponse;
}

rpc! {
pub struct RestoreShardParams {
pub seed_fingerprint: SeedFingerprint,
pub timestamp: Option<u32>,
}
}

rpc! {
pub enum RestoreShardResponse {
Success { shard: Shard },
Error { error: String },
NotFound,
}
}

impl Request for RequestRestoreShard {
type Error = Error;
type Request = RestoreShardParams;
type Response = RestoreShardResponse;
}

rpc! {
pub struct PassportMagicBackupStatusParams {
pub seed_fingerprint: SeedFingerprint,
pub timestamp: Option<u32>,
}
}

rpc! {
pub struct PassportMagicBackupStatusResponse {
pub shard_backup_found: bool,
}
}

impl Request for RequestPassportMagicBackupStatus {
type Error = Error;
type Request = PassportMagicBackupStatusParams;
type Response = PassportMagicBackupStatusResponse;
}

rpc! {
pub struct UploadMagicBackupParams {
pub seed_fingerprint: SeedFingerprint,
pub total_size: Option<u64>,
pub hash: [u8; 32],
}
}

rpc! {
pub enum UploadMagicBackupResponse {
Success,
Error { error: String },
}
}

rpc! {
pub struct UploadMagicBackupPartHeader {}
}

impl Upload for UploadMagicBackup {
type Error = Error;
type Request = UploadMagicBackupParams;
type PartHeader = UploadMagicBackupPartHeader;
type Response = UploadMagicBackupResponse;
}

rpc! {
pub struct DownloadMagicBackupParams {
pub seed_fingerprint: SeedFingerprint,
}
}

rpc! {
pub struct BackupMetadata {
pub total_size: Option<u64>,
}
}

rpc! {
pub enum DownloadMagicBackupHeader {
Found(BackupMetadata),
NotFound,
Error { error: String },
}
}

impl Download for DownloadMagicBackup {
type Error = Error;
type Request = DownloadMagicBackupParams;
type ResponseHeader = DownloadMagicBackupHeader;
type PartHeader = Empty;
}
97 changes: 97 additions & 0 deletions ql-api/src/bitcoin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
use ql_rpc::{Request, Subscription};

use crate::{Empty, Error};

// COMMON TYPES

rpc! {
pub struct ActiveSeedFingerprint {
pub fingerprint: String,
pub has_passphrase: bool,
}
}

// APP ROUTES

app_routes! {
crate::app_id::BITCOIN => {
RequestSignPsbt: Request = 1,
SubscribeAccountUpdated: Subscription = 2,
RequestPassportActiveSeedFingerprint: Request = 3,
SubscribePassportActiveSeedFingerprint: Subscription = 4,
}
}

rpc! {
pub struct SignPsbtParams {
pub account_id: String,
pub psbt: Vec<u8>,
}
}

rpc! {
pub enum SignPsbtResponse {
Signed { psbt: Vec<u8> },
Rejected,
Error { error: String },
}
}

impl Request for RequestSignPsbt {
type Error = Error;
type Request = SignPsbtParams;
type Response = SignPsbtResponse;
}

rpc! {
pub struct AccountUpdatedEvent {
pub account_id: String,
pub update: Vec<u8>,
}
}

impl Subscription for SubscribeAccountUpdated {
type Error = Error;
type Request = Empty;
type Event = AccountUpdatedEvent;
}

impl Subscription for SubscribePassportActiveSeedFingerprint {
type Error = Error;
type Request = Empty;
type Event = ActiveSeedFingerprint;
}

impl Request for RequestPassportActiveSeedFingerprint {
type Error = Error;
type Request = Empty;
type Response = ActiveSeedFingerprint;
}

// SERVICE ROUTES

service_routes! {
crate::service_id::BITCOIN => {
RequestBroadcastTransaction: Request = 1,
}
}

rpc! {
pub struct BroadcastTransactionParams {
pub account_id: String,
pub psbt: Vec<u8>,
}
}

rpc! {
pub enum BroadcastTransactionResponse {
Broadcast { txid: String },
Error { error: String },
}
}

impl Request for RequestBroadcastTransaction {
type Error = Error;
type Request = BroadcastTransactionParams;
type Response = BroadcastTransactionResponse;
}
Loading