/keepin_iOS_SDK

Primary LanguageSwiftMIT LicenseMIT

Metadium DID SDK for iOS

CI Status Version License Platform

DID 생성 및 키 관리 기능과 Verifiable Credential의 서명과 검증에 대한 기능을 제공한다.

Example

To run the example project, clone the repo, and run pod install from the Example directory first.

Requirements

Installation

KeepinCRUD is available through CocoaPods. To install it, simply add the following line to your Podfile:

source 'https://github.com/CocoaPods/Specs.git'
source 'https://github.com/METADIUM/Web3Swift-iOS'

target 'project' do
    pod 'KeepinCRUD', :git => 'https://github.com/METADIUM/Keepin_iOS_SDK.git'
end

Use It

지갑 키 생성

추가로 Metadium mainnet, testnet 을 사용시에는 apiKey 는 Metadium 운영부서에서 발급을 받아야 합니다.

//delegate url, node url, resolver url, didPrefix를 직접 설정할 때 초기화 부분에 셋팅합니다.
/**
 * 개발서버 delegateUrl: https://testdelegator.metadium.com, nodeUrl:  https://api.metadium.com/dev, resolverUrl: https://testnetresolver.metadium.com/1.0/identifiers/,  didPrefix: did:meta:testnet:
 * 운영서버 delegateUrl: https://delegator.metadium.com, nodeUrl:  https://api.metadium.com/prod, resolverUrl: https://resolver.metadium.com/1.0/identifiers/, didPrefix: did:meta:
 */

let delegator = MetaDelegator.init(delegatorUrl: "https://testdelegator.metadium.com",
                                    nodeUrl: "https://api.metadium.com/dev",
                                    resolverUrl: "https://testnetresolver.metadium.com/1.0/identifiers/",
                                    didPrefix: "did:meta:testnet:",
                                    api_key: "testKey")

let key = wallet.createKey()

//key.privateKey, key.publicKey, key.address

load KeyStore

let delegator = MetaDelegator.init(delegatorUrl: "https://testdelegator.metadium.com",
                                    nodeUrl: "https://api.metadium.com/dev",
                                    resolverUrl: "https://testnetresolver.metadium.com/1.0/identifiers/",
                                    didPrefix: "did:meta:testnet:",
                                    api_key: "testKey")

let wallet = MetaWallet.init(delegator: delegator, privateKey: "0xb7fddf3e1645b2f2ef8e1f427ec2ae76cc6989fd33999f065bc48cb39d6c2336", did: "did:meta:testnet:0000000000000000000000000000000000000000000000000000000000002f4c")

key sign

let data = "test data".data(using: .utf8)
let (signature, r, s, v) = wallet.getSignature(data: data!)

로컬 privatekey assign 및 sign값

let wallet = wallet.assignPrivateKey(privateKey: privateKey)
let (signatureData, r, s, v)  = wallt.getWalletSignature()

DID 생성

let (signData, r, s, v) = wallet.getCreateKeySignature()

delegator.createIdentityDelegated(signData: signData!, r: r, s: s, v: v) { (type, txId, error) in
    if error != nil {
        return
    }
    
    DispatchQueue.global().asyncAfter(deadline: .now() + 0.3) {
        self.wallet.transactionReceipt(type: type!, txId: txId!) { (error, receipt) in
        
            if error != nil {
                return
            }
        
            if receipt == nil {
                self.wallet.transactionReceipt(type: type!, txId: txId!, complection: nil)
            
                return
            }
        
            if receipt!.status == .success {
                //Todo...
            }
        }
    }
}

}

서비스 키 생성

let serviceKey = wallet.createServiceKey()

Delegate

add_public_key_delegated : 지갑 publicKey를 publickey resolver에 delegate를 통해 등록

let (signData, r, s, v) = self.wallet.getPublicKeySignature()

self.delegator.addPublicKeyDelegated(signData: signData!, r: r, s: s, v: v) { (type, txId, error) in

    if error != nil {
        return
        }

    DispatchQueue.global().asyncAfter(deadline: .now() + 0.3) {
        self.wallet.transactionReceipt(type: type!, txId: txId!) { (error, receipt) in
            if error != nil {
                return
            }
        
            if receipt == nil {
                self.wallet.transactionReceipt(type: type!, txId: txId!, complection: nil)
            
                return
            }
        
            print("status: \(receipt!.status), hash : \(receipt!.transactionHash)")
        
            if receipt!.status == .success {
                //Todo...
            }
        }
    }
}

}

add_key_delegated : 서비스키를 service_key resolver에 delegate를 통해 등록

let (addr, signData, servieId, r, s, v) = self.wallet.getSignServiceId(serviceID: "5933e64b-cb34-11ea-9e0f-020c6496fbdc", serviceAddress: address!)

self.delegator.addKeyDelegated(address: addr, signData: signData!, serviceId: servieId, r: r, s: s, v: v) { (type, txId, error) in 
    if error != nil {
        return
    }
    
    DispatchQueue.global().asyncAfter(deadline: .now() + 0.3) {
        self.wallet.transactionReceipt(type: type!, txId: txId!) { (error, receipt) in
            if error != nil {
                return
            }
        
            if receipt == nil {
                self.wallet.transactionReceipt(type: type!, txId: txId!, complection: nil)
            
                return
            }
        
            print("status: \(receipt!.status), hash : \(receipt!.transactionHash)")
        
            if receipt!.status == .success {
                //Todo...
            }
            else {
                //Todo...
            }
        }
    }
}

}

remove_keys_delegated

let (_, r, s, v) = self.wallet!.getRemoveKeySign()

self.delegator?.removeKeyDelegated(r: r, s: s, v: v, complection: { (type, txId, error) in
    if error != nil {
        return
    }

    DispatchQueue.global().asyncAfter(deadline: .now() + 0.3) {
        self.wallet?.transactionReceipt(type: type!, txId: txId!, complection: { (error, receipt) in
        
            if receipt!.status == .success {
                //Todo..
            }
        })
    }
})

remove_public_key_delegated

let (_, r, s, v) = self.wallet!.getRemovePublicKeySign()

self.delegator?.removePublicKeyDelegated(r: r, s: s, v: v, complection: { (type, txId, error) in
    if error != nil {
        return
    }

    DispatchQueue.global().asyncAfter(deadline: .now() + 0.3) {
        self.wallet?.transactionReceipt(type: type!, txId: txId!, complection: { (error, receipt) in
        
            if receipt!.status == .success {
                //Todo...
            }
        })
    }
})

remove_associated_address_delegated

let (_, r, s, v) = self.wallet!.getRemoveAssociatedAddressSign()

self.delegator?.removeAssociatedAddressDelegated(r: r, s: s, v: v, complection: { (type, txId, error) in
    if error != nil {
        return
    }

    DispatchQueue.global().asyncAfter(deadline: .now() + 0.3) {
        self.wallet?.transactionReceipt(type: type!, txId: txId!, complection: { (error, receipt) in
        
            if receipt!.status == .success {
                //Todo...
            }
        })
    }
})

Get DID Document

DID Document 정보를 얻는다.

let did = self.wallet?.getDid()

self.wallet?.reqDiDDocument(did: did!, complection: { (document, error) in
    if error != nil {
        return
    }
    
    let didDocument = document
})

Verifiable Credential

Verifiable credential, Verifiable presentation 발급 및 검증

Issue Credential

verifiable credential을 발급한다.

발급자(Issuer)는 DID가 생성되어 있어야 하며 credential의 이름(types), 사용자(holder)의 DID, 발급할 내용(claims)가 필수로 필요하다.

let issuanceDate = Date()
let expirationDate = Date()
let nonce = Data.randomBytes(length: 32)?.base64EncodedString()

let vc = try? self.wallet?.issueCredential(types: ["NameCredential"],
                                           id: "http://aa.metadium.com/credential/name/343",
                                           nonce: nonce,
                                           issuanceDate: issuanceDate,
                                           expirationDate: expirationDate,
                                           ownerDid: "did:meta:00000...00003159",
                                           subjects: ["name": "Keepin"]) as! JWSObject


let serializedVC = try? vc?.serialize()

Issue Presentation

verifiable presentation을 발급한다.

사용자(holder)는 DID가 생성되어 있어야 하며 검증자(verifier)에게 전달할 발급받은 credential을 포함해야 한다.

let issuanceDate = Date()
let expirationDate = Date()
let nonce = Data.randomBytes(length: 32)?.base64EncodedString()

let vp = try? self.wallet?.issuePresentation(types: ["TestPresentation"],
                                             id: "http://aa.metadium.com/presentation/343",
                                             nonce: nonce,
                                             issuanceDate: issuanceDate,
                                             expirationDate: expirationDate,
                                             vcList: [serializedVC]) as! JWSObject

let serializedVP = try? vp?.serialize()

Verify Credential or Presentation

네트워크가 메인넷이 안닌 경우 검증 전에 resolver URL 이 설정되어 있어야 정상적이 검증이 가능하다.

사용자 또는 검증자가 credential 또는 presentation 을 검증을 한다.

let jws = try? JWSObject.init(string: serializedVC)
let jwt = try? JWT.init(jsonData: jws!.payload)

let expireDate = jwt!.expirationTime

let isVerify =  try? self.wallet?.verify(jwt: jws!)

if isVerify == false {
    //검증실패
}
else if (expireDate != nil && expireDate! > Date()) {
    // 유효기간 초과
}

Author

jinsikhan, jshan@coinplug.com

License

KeepinCRUD is available under the MIT license. See the LICENSE file for more info.