diff --git a/android/app/capacitor.build.gradle b/android/app/capacitor.build.gradle index 223bdf34..d8b1349f 100644 --- a/android/app/capacitor.build.gradle +++ b/android/app/capacitor.build.gradle @@ -12,6 +12,7 @@ dependencies { implementation project(':capacitor-app') implementation project(':capacitor-app-launcher') implementation project(':capacitor-clipboard') + implementation project(':capacitor-filesystem') implementation project(':capacitor-splash-screen') implementation project(':capacitor-status-bar') implementation "com.android.support:support-v4:26.+" diff --git a/android/app/src/main/assets/capacitor.plugins.json b/android/app/src/main/assets/capacitor.plugins.json index 68083e68..704b6f1e 100644 --- a/android/app/src/main/assets/capacitor.plugins.json +++ b/android/app/src/main/assets/capacitor.plugins.json @@ -11,6 +11,10 @@ "pkg": "@capacitor/clipboard", "classpath": "com.capacitorjs.plugins.clipboard.ClipboardPlugin" }, + { + "pkg": "@capacitor/filesystem", + "classpath": "com.capacitorjs.plugins.filesystem.FilesystemPlugin" + }, { "pkg": "@capacitor/splash-screen", "classpath": "com.capacitorjs.plugins.splashscreen.SplashScreenPlugin" diff --git a/android/capacitor.settings.gradle b/android/capacitor.settings.gradle index 7c2c63c2..8e685785 100644 --- a/android/capacitor.settings.gradle +++ b/android/capacitor.settings.gradle @@ -11,6 +11,9 @@ project(':capacitor-app-launcher').projectDir = new File('../node_modules/@capac include ':capacitor-clipboard' project(':capacitor-clipboard').projectDir = new File('../node_modules/@capacitor/clipboard/android') +include ':capacitor-filesystem' +project(':capacitor-filesystem').projectDir = new File('../node_modules/@capacitor/filesystem/android') + include ':capacitor-splash-screen' project(':capacitor-splash-screen').projectDir = new File('../node_modules/@capacitor/splash-screen/android') diff --git a/package.json b/package.json index 891b24b4..a184e6d9 100644 --- a/package.json +++ b/package.json @@ -37,9 +37,9 @@ "apply-diagnostic-modules": "node apply-diagnostic-modules.js" }, "dependencies": { - "@airgap/angular-core": "0.0.20", - "@airgap/angular-ngrx": "0.0.20", - "@airgap/coinlib-core": "0.12.2", + "@airgap/angular-core": "0.0.21", + "@airgap/angular-ngrx": "0.0.21", + "@airgap/coinlib-core": "0.12.3", "@airgap/sapling-wasm": "0.0.6", "@angular/common": "^11.2.9", "@angular/core": "^11.2.9", @@ -52,6 +52,7 @@ "@capacitor/app-launcher": "^1.0.6", "@capacitor/clipboard": "^1.0.5", "@capacitor/core": "^3.2.5", + "@capacitor/filesystem": "1.0.6", "@capacitor/ios": "^3.2.5", "@capacitor/splash-screen": "^1.1.5", "@capacitor/status-bar": "^1.0.5", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 6b6d7132..bd42f974 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -14,6 +14,7 @@ import { SerializerService, SPLASH_SCREEN_PLUGIN, STATUS_BAR_PLUGIN, + FILESYSTEM_PLUGIN, UiEventService } from '@airgap/angular-core' import { AirGapAngularNgRxModule } from '@airgap/angular-ngrx' @@ -62,6 +63,7 @@ import { SecureStorageService } from './services/secure-storage/secure-storage.s import { ShareUrlService } from './services/share-url/share-url.service' import { StartupChecksService } from './services/startup-checks/startup-checks.service' import { VaultStorageService } from './services/storage/storage.service' +import { Filesystem } from '@capacitor/filesystem' export function createTranslateLoader(http: HttpClient): AirGapTranslateLoader { return new AirGapTranslateLoader(http, { prefix: './assets/i18n/', suffix: '.json' }) @@ -108,6 +110,7 @@ export function createTranslateLoader(http: HttpClient): AirGapTranslateLoader { { provide: APP_LAUNCHER_PLUGIN, useValue: AppLauncher }, { provide: CAMERA_PREVIEW_PLUGIN, useValue: CameraPreview }, { provide: CLIPBOARD_PLUGIN, useValue: Clipboard }, + { provide: FILESYSTEM_PLUGIN, useValue: Filesystem }, { provide: SAPLING_PLUGIN, useValue: SaplingNative }, { provide: SECURITY_UTILS_PLUGIN, useValue: SecurityUtils }, { provide: SPLASH_SCREEN_PLUGIN, useValue: SplashScreen }, @@ -162,4 +165,4 @@ export function createTranslateLoader(http: HttpClient): AirGapTranslateLoader { ], bootstrap: [AppComponent] }) -export class AppModule {} +export class AppModule { } diff --git a/src/app/pages/deserialized-detail/deserialized-detail.effects.ts b/src/app/pages/deserialized-detail/deserialized-detail.effects.ts index 38e0523e..b48aff8c 100644 --- a/src/app/pages/deserialized-detail/deserialized-detail.effects.ts +++ b/src/app/pages/deserialized-detail/deserialized-detail.effects.ts @@ -133,7 +133,7 @@ export class DeserializedDetailEffects { private readonly keyPairService: KeyPairService, private readonly transactionService: TransactionService, private readonly interactionService: InteractionService - ) {} + ) { } private async loadNavigationData(): Promise { const state = this.navigationService.getState() @@ -235,7 +235,8 @@ export class DeserializedDetailEffects { id: request.id, details, data: request.payload as UnsignedTransaction, - wallet + wallet, + originalProtocolIdentifier: request.protocol !== wallet.protocol.symbol ? request.protocol : undefined } } ) @@ -263,7 +264,8 @@ export class DeserializedDetailEffects { protocol: request.protocol, data, blake2bHash, - wallet + wallet, + originalProtocolIdentifier: request.protocol !== wallet.protocol.symbol ? request.protocol : undefined } } ) @@ -308,7 +310,8 @@ export class DeserializedDetailEffects { transaction: signed, callbackURL: transaction.data.callbackURL }, - wallet: transaction.wallet + wallet: transaction.wallet, + originalProtocolIdentifier: transaction.originalProtocolIdentifier } } ) @@ -362,7 +365,8 @@ export class DeserializedDetailEffects { signature, callbackURL: message.data.callbackURL }, - wallet: message.wallet + wallet: message.wallet, + originalProtocolIdentifier: message.originalProtocolIdentifier } } ) @@ -425,20 +429,20 @@ export class DeserializedDetailEffects { } private async navigateWithSignedTransactions(transactions: DeserializedSignedTransaction[]): Promise { - const broadcastUrl: IACMessageDefinitionObjectV3[] = await this.generateTransactionBroadcastUrl(transactions) + const messages: IACMessageDefinitionObjectV3[] = await this.generateTransactionIACMessages(transactions) this.interactionService.startInteraction({ operationType: InteractionOperationType.TRANSACTION_BROADCAST, - iacMessage: broadcastUrl, + iacMessage: messages, wallets: transactions.map((transaction: DeserializedSignedTransaction): AirGapWallet => transaction.wallet), signedTxs: transactions.map((transaction: DeserializedSignedTransaction): string => transaction.data.transaction) }) } - private async generateTransactionBroadcastUrl(transactions: DeserializedSignedTransaction[]): Promise { + private async generateTransactionIACMessages(transactions: DeserializedSignedTransaction[]): Promise { const signResponses: IACMessageDefinitionObjectV3[] = transactions.map( (transaction: DeserializedSignedTransaction): IACMessageDefinitionObjectV3 => ({ id: transaction.id, - protocol: transaction.wallet.protocol.identifier, + protocol: transaction.originalProtocolIdentifier ?? transaction.wallet.protocol.identifier, type: IACMessageType.TransactionSignResponse, payload: { accountIdentifier: transaction.data.accountIdentifier, @@ -450,31 +454,30 @@ export class DeserializedDetailEffects { } }) ) - - return this.generateBroadcastUrl(signResponses, transactions[0]?.data.callbackURL) + return signResponses } private async navigateWithSignedMessages(messages: DeserializedSignedMessage[]): Promise { - const broadcastUrl: IACMessageDefinitionObjectV3[] = await this.generateMessageBroadcastUrl(messages) + const iacMessages: IACMessageDefinitionObjectV3[] = await this.generateIACMessages(messages) this.interactionService.startInteraction({ operationType: InteractionOperationType.MESSAGE_SIGN_REQUEST, - iacMessage: broadcastUrl, + iacMessage: iacMessages, messageSignResponse: messages[0] !== undefined ? { - message: messages[0].data.message, - publicKey: messages[0].data.publicKey, - signature: messages[0].data.signature - } + message: messages[0].data.message, + publicKey: messages[0].data.publicKey, + signature: messages[0].data.signature + } : undefined }) } - private async generateMessageBroadcastUrl(messages: DeserializedSignedMessage[]): Promise { + private async generateIACMessages(messages: DeserializedSignedMessage[]): Promise { const signResponses: IACMessageDefinitionObjectV3[] = messages.map( (message: DeserializedSignedMessage): IACMessageDefinitionObjectV3 => ({ id: message.id, - protocol: message.protocol, + protocol: message.originalProtocolIdentifier ?? message.protocol, type: IACMessageType.MessageSignResponse, payload: { message: message.data.message, @@ -483,17 +486,7 @@ export class DeserializedDetailEffects { } }) ) - - return this.generateBroadcastUrl(signResponses, messages[0]?.data.callbackURL) - } - - private async generateBroadcastUrl( - messages: IACMessageDefinitionObjectV3[], - _callbackUrl?: string - ): Promise { - // const serialized: string | string[] = await this.serializerService.serialize(messages) - - return messages // `${callbackUrl || 'airgap-wallet://?d='}${typeof serialized === 'string' ? serialized : serialized.join(',')}` + return signResponses } private async checkIfSaplingTransaction(transaction: UnsignedTransaction, protocolIdentifier: ProtocolSymbols): Promise { diff --git a/src/app/pages/deserialized-detail/deserialized.detail.types.ts b/src/app/pages/deserialized-detail/deserialized.detail.types.ts index 64462444..2fe8eb5c 100644 --- a/src/app/pages/deserialized-detail/deserialized.detail.types.ts +++ b/src/app/pages/deserialized-detail/deserialized.detail.types.ts @@ -50,6 +50,7 @@ export interface DeserializedUnsignedTransaction { details: IAirGapTransaction[] data: UnsignedTransaction wallet: AirGapWallet + originalProtocolIdentifier?: ProtocolSymbols } export interface DeserializedSignedTransaction { @@ -57,7 +58,8 @@ export interface DeserializedSignedTransaction { id: number details: IAirGapTransaction[] data: SignedTransaction & Pick - wallet: AirGapWallet + wallet: AirGapWallet, + originalProtocolIdentifier?: ProtocolSymbols } export type DeserializedTransaction = DeserializedUnsignedTransaction | DeserializedSignedTransaction @@ -75,6 +77,7 @@ export interface DeserializedUnsignedMessage { data: MessageSignRequest blake2bHash: string | undefined wallet: AirGapWallet | undefined + originalProtocolIdentifier?: ProtocolSymbols } export interface DeserializedSignedMessage { @@ -83,6 +86,7 @@ export interface DeserializedSignedMessage { protocol: ProtocolSymbols | undefined data: MessageSignResponse & Pick wallet: AirGapWallet | undefined + originalProtocolIdentifier?: ProtocolSymbols } export type DeserializedMessage = DeserializedUnsignedMessage | DeserializedSignedMessage diff --git a/yarn.lock b/yarn.lock index f750a20d..b440e68a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,24 +2,24 @@ # yarn lockfile v1 -"@airgap/angular-core@0.0.20": - version "0.0.20" - resolved "https://registry.yarnpkg.com/@airgap/angular-core/-/angular-core-0.0.20.tgz#af6be8723f89cf1026a31b532ba8b3987dca67b4" - integrity sha512-CnI7IDOjxddjzxJSkz3OuDTz78O/SZTTRDyDiRNxnfNlV7MDgcUhAVuIlSPSa+ThKmfVYIyHr0T66gxPCb2M+g== +"@airgap/angular-core@0.0.21": + version "0.0.21" + resolved "https://registry.yarnpkg.com/@airgap/angular-core/-/angular-core-0.0.21.tgz#10e7d4dbef9d6573a4e40c78d8ab8090f5390d18" + integrity sha512-9zh0/hs0ble8Ms3xfNBRb37HSCJTUcv3Jq23s4nW7U/88j2ZkTsgnbAr2bx+r16oanrdlkw9+/552TwkFVKMSw== dependencies: tslib "^2.2.0" -"@airgap/angular-ngrx@0.0.20": - version "0.0.20" - resolved "https://registry.yarnpkg.com/@airgap/angular-ngrx/-/angular-ngrx-0.0.20.tgz#7cdcb78e51b4b45336996953bd3da248dff694f4" - integrity sha512-fESWKi27UINRlRhzoFgw92kfGRc/5PfIjAd9lQQzym73K7KZwcolduAQYboS48d2VK5vv4aIXfaqEn8FDS23eQ== +"@airgap/angular-ngrx@0.0.21": + version "0.0.21" + resolved "https://registry.yarnpkg.com/@airgap/angular-ngrx/-/angular-ngrx-0.0.21.tgz#fa84be8baa11fe648a41062e1b42abd2aea884e4" + integrity sha512-UeQ9Vp5YsJjT+lgq+bNWqXZF8vTutNarXnOpiqvsQXh34XWPA1aGr5I+ajk9N2E4F4K7DRvRu7Az3SQtBIZWQw== dependencies: tslib "^2.2.0" -"@airgap/coinlib-core@0.12.2": - version "0.12.2" - resolved "https://registry.yarnpkg.com/@airgap/coinlib-core/-/coinlib-core-0.12.2.tgz#0461656f55f805729dbeda571100739754a2e6d5" - integrity sha512-Aap0WQWXY4MERwh6SijhC47jG0+wXZRtem4Iim55lm3og46LQ8PGae5Opu+DKM0B9ipK3AC6qpzN8GvUVbE2xw== +"@airgap/coinlib-core@0.12.3": + version "0.12.3" + resolved "https://registry.yarnpkg.com/@airgap/coinlib-core/-/coinlib-core-0.12.3.tgz#18759298509b02f0922373218cd4a8001825ce69" + integrity sha512-jgZdrTtu+WdMT0ZJkodc6N6E6CyV2okAl/4tYf9zzG9atVo//kAXePXth6UwkSQ/laM8i/dibEgkx+YlUjfTgg== dependencies: "@airgap/sapling-wasm" "0.0.5" "@polkadot/util" "2.0.1" @@ -1188,6 +1188,11 @@ dependencies: tslib "^2.1.0" +"@capacitor/filesystem@1.0.6": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@capacitor/filesystem/-/filesystem-1.0.6.tgz#b837585e6b5d48dc705ee89e49cc7c6aeb8874ec" + integrity sha512-8xqUbDZFGBMhgqoBSn9wEd9OBPdHIRegQ9zCCZcpHNf3FFAIby1ck+aDFnoq+Da49xhD6ks1SKCBSxz/26qWTw== + "@capacitor/ios@^3.2.5": version "3.2.5" resolved "https://registry.yarnpkg.com/@capacitor/ios/-/ios-3.2.5.tgz#2d988aa08caa3c72de3c20471fc084f0fdf26a40"