|  | 
|  | 1 | +package com.r3.corda.lib.tokens.bridging.flows | 
|  | 2 | + | 
|  | 3 | +import com.r3.corda.lib.tokens.workflows.utilities.tokenAmountsByToken | 
|  | 4 | +import net.corda.core.identity.PartyAndCertificate | 
|  | 5 | +import net.corda.core.node.AppServiceHub | 
|  | 6 | +import net.corda.core.node.services.CordaService | 
|  | 7 | +import net.corda.core.serialization.SingletonSerializeAsToken | 
|  | 8 | +import net.corda.samples.stockpaydividend.states.StockState | 
|  | 9 | +import java.util.* | 
|  | 10 | + | 
|  | 11 | +@CordaService | 
|  | 12 | +class BridgingAuthorityBootstrapService(appServiceHub: AppServiceHub) : SingletonSerializeAsToken() { | 
|  | 13 | +    val holdingIdentityPartyAndCertificate: PartyAndCertificate | 
|  | 14 | +    val bridgeAuthorityParty = appServiceHub.ourIdentity() | 
|  | 15 | + | 
|  | 16 | +    init { | 
|  | 17 | +        val cfg = appServiceHub.getAppContext().config | 
|  | 18 | +        val holdingIdentityLabel = UUID.fromString(cfg.getString("holdingIdentityLabel")) | 
|  | 19 | +        val holdingIdentityPublicKey = appServiceHub | 
|  | 20 | +            .identityService | 
|  | 21 | +            .publicKeysForExternalId(holdingIdentityLabel) | 
|  | 22 | +            .singleOrNull() | 
|  | 23 | +        holdingIdentityPartyAndCertificate = if (holdingIdentityPublicKey == null) { | 
|  | 24 | +            // Generate a new key pair and self-signed certificate for the holding identity | 
|  | 25 | +            appServiceHub.keyManagementService.freshKeyAndCert( | 
|  | 26 | +                identity = requireNotNull(appServiceHub.identityService.certificateFromKey(bridgeAuthorityParty.owningKey)) { | 
|  | 27 | +                    "Could not find certificate for key ${bridgeAuthorityParty.owningKey}" | 
|  | 28 | +                }, | 
|  | 29 | +                revocationEnabled = false, | 
|  | 30 | +                externalId = holdingIdentityLabel | 
|  | 31 | +            ) | 
|  | 32 | +        } else { | 
|  | 33 | +            // Reuse the existing key pair and certificate for the holding identity | 
|  | 34 | +            checkNotNull(appServiceHub.identityService.certificateFromKey(holdingIdentityPublicKey)) { | 
|  | 35 | +                "Could not find certificate for key $holdingIdentityPublicKey" | 
|  | 36 | +            } | 
|  | 37 | +        } | 
|  | 38 | + | 
|  | 39 | +        onStartup(appServiceHub) | 
|  | 40 | +    } | 
|  | 41 | + | 
|  | 42 | +    private fun onStartup(appServiceHub: AppServiceHub) { | 
|  | 43 | +        //Retrieve states from receiver | 
|  | 44 | +        val receivedStockStatesPages = appServiceHub.vaultService.queryBy(StockState::class.java).states | 
|  | 45 | +        val receivedStockStates = receivedStockStatesPages.map { it.state.data } | 
|  | 46 | + | 
|  | 47 | +        callFlow(receivedStockStates, appServiceHub) | 
|  | 48 | +        addVaultListener(appServiceHub) | 
|  | 49 | +    } | 
|  | 50 | + | 
|  | 51 | +    private fun addVaultListener(appServiceHub: AppServiceHub) { | 
|  | 52 | +        appServiceHub.vaultService.trackBy(StockState::class.java).updates.subscribe { | 
|  | 53 | +            val producedStockStates = it.produced.map { it.state.data } | 
|  | 54 | +            callFlow(producedStockStates, appServiceHub) | 
|  | 55 | +        } | 
|  | 56 | +    } | 
|  | 57 | + | 
|  | 58 | +    private fun callFlow(producedStockStates: Collection<StockState>, appServiceHub: AppServiceHub) { | 
|  | 59 | +        producedStockStates.forEach { stockState -> | 
|  | 60 | +            val tokens = appServiceHub.vaultService.tokenAmountsByToken( | 
|  | 61 | +                stockState.toPointer( | 
|  | 62 | +                    stockState.javaClass | 
|  | 63 | +                ) | 
|  | 64 | +            ).states | 
|  | 65 | +            appServiceHub.startFlow( | 
|  | 66 | +                BridgeFungibleTokenFlow( | 
|  | 67 | +                    holdingIdentityPartyAndCertificate.party, | 
|  | 68 | +                    emptyList(), | 
|  | 69 | +                    tokens.first(), //TODO handle multiple tokens | 
|  | 70 | +                    bridgeAuthorityParty | 
|  | 71 | +                ) | 
|  | 72 | +            ) | 
|  | 73 | +        } | 
|  | 74 | +    } | 
|  | 75 | + | 
|  | 76 | +    private fun AppServiceHub.ourIdentity() = myInfo.legalIdentities.first() | 
|  | 77 | +} | 
0 commit comments