/// <summary> /// Creates a new wallet. /// </summary> /// <remarks> /// <para>Each created wallet is given a name which is then subsequently used to open it /// with the <see cref="OpenWalletAsync(string, string, string)"/> or delete it using the /// <see cref="DeleteWalletAsync(string, string)"/> static methods. /// <note type="note">Wallet names must be unique within a pool.</note> /// </para> /// <para> /// When creating a new Wallet the <paramref name="type"/> parameter can be null or "default" to /// use the default wallet implementation, or a type name specified in an earlier call to the /// <see cref="RegisterWalletTypeAsync(string, WalletType)"/> method to use a custom wallet implementation. /// Attempting to use a wallet type that hasn't previously been registered will result in an error. /// </para> /// <para>The <paramref name="config"/> parameter allows configuration values to be passed to the wallet /// when it is created. When using the default wallet this value can be null to use the default /// wallet configuration or a JSON string with the following format can be used: /// <code> /// { /// "freshness_time": int /// } /// </code> /// The value of the <c>freshness_time</c> key is an integer representing the number of seconds /// a value in the wallet will remain valid before expiring. If not specified the default value /// for <c>freshness_time</c> is 24 * 60 seconds. /// </para> /// <para>If using a custom wallet type the content of the <paramref name="config"/> parameter can /// be any string value; it is up to the custom wallet type implementer to interpret the value. /// </para> /// <para>The <paramref name="credentials"/> parameter is unused in the default wallet at present, /// however the value can be used by custom wallet implementations; it is up to the custom wallet /// type implementer to interpret the value.</para> /// </remarks> /// <param name="poolName">The name of the pool the wallet is associated with.</param> /// <param name="name">The name of the wallet.</param> /// <param name="type">The type of the wallet. </param> /// <param name="config">The wallet configuration JSON.</param> /// <param name="credentials">The wallet credentials JSON or null to use the default credentials.</param> /// <returns>An asynchronous <see cref="Task"/> with no return value the completes when the operation has finished.</returns> public static Task CreateWalletAsync(string poolName, string name, string type, string config, string credentials) { ParamGuard.NotNullOrWhiteSpace(poolName, "poolName"); ParamGuard.NotNullOrWhiteSpace(name, "name"); var taskCompletionSource = new TaskCompletionSource <bool>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var result = NativeMethods.indy_create_wallet( commandHandle, poolName, name, type, config, credentials, CallbackHelper.TaskCompletingNoValueCallback); CallbackHelper.CheckResult(result); return(taskCompletionSource.Task); }
/// <summary> /// Builds Indy request for doing tokens minting /// according to this payment method. /// /// Note this endpoint is EXPERIMENTAL. Function signature and behaviour may change /// in the future releases. /// </summary> /// <returns>Indy request for doing tokens minting.</returns> /// <param name="wallet">Wallet.</param> /// <param name="submitterDid">Submitter did.</param> /// <param name="outputsJson">The list of UTXO outputs as json array: /// [{ /// paymentAddress: <str>, // payment address used as output /// amount: <int>, // amount of tokens to transfer to this payment address /// extra: <str>, // optional data /// }]</param> /// <param name="extra">Optional information for payment operation</param> public static Task <PaymentResult> BuildMintRequestAsync(Wallet wallet, string submitterDid, string outputsJson, string extra) { ParamGuard.NotNull(wallet, "wallet"); ParamGuard.NotNullOrWhiteSpace(submitterDid, "submitterDid"); ParamGuard.NotNullOrWhiteSpace(outputsJson, "outputsJson"); var taskCompletionSource = new TaskCompletionSource <PaymentResult>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var result = NativeMethods.indy_build_mint_req( commandHandle, wallet.Handle, submitterDid, outputsJson, extra, BuildMintRequestCallback); CallbackHelper.CheckResult(result); return(taskCompletionSource.Task); }
/// <summary> /// Gets the endpoint details for the specified DID. /// </summary> /// <remarks> /// If the <paramref name="did"/> is present in the <paramref name="wallet"/> and is considered "fresh" then /// the endpoint will be resolved from the wallet. If, on the other hand, the DID is not present in the wallet or /// is not fresh then the details will be resolved from the <paramref name="pool"/> and will be cached in the wallet. /// </remarks> /// <param name="wallet">The wallet containing the DID.</param> /// <param name="pool">The pool to resolve the endpoint data from if not present in the wallet.</param> /// <param name="did">The DID to get the endpoint data for.</param> /// <returns>An asynchronous <see cref="Task{T}"/> that resolves to an <see cref="EndpointForDidResult"/> containing the endpoint information /// associated with the DID.</returns> public static Task <EndpointForDidResult> GetEndpointForDidAsync(Wallet wallet, Pool pool, string did) { ParamGuard.NotNull(wallet, "wallet"); ParamGuard.NotNull(pool, "pool"); ParamGuard.NotNullOrWhiteSpace(did, "did"); var taskCompletionSource = new TaskCompletionSource <EndpointForDidResult>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var commandResult = NativeMethods.indy_get_endpoint_for_did( commandHandle, wallet.Handle, pool.Handle, did, GetEndpointForDidCompletedCallback ); CallbackHelper.CheckResult(commandResult); return(taskCompletionSource.Task); }
/// <summary> /// Builds a GET_ATTRIB ledger request. /// </summary> /// <remarks> /// <para> /// Builds a request message that is suitable for requesting an attribute from the /// ledger. /// </para> /// </remarks> /// <param name="submitterDid">The DID of the submitter.</param> /// <param name="targetDid">The target DID.</param> /// <param name="raw">The name of the attribute to get.</param> /// <param name="hash"></param> /// <param name="enc"></param> /// <returns>An asynchronous <see cref="Task{T}"/> that resolves to a <see cref="string"/> /// containing the request JSON. </returns> public static Task <string> BuildGetAttribRequestAsync(string submitterDid, string targetDid, string raw, string hash, string enc) { ParamGuard.NotNullOrWhiteSpace(targetDid, "targetDid"); var taskCompletionSource = new TaskCompletionSource <string>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var result = NativeMethods.indy_build_get_attrib_request( commandHandle, submitterDid, targetDid, raw, hash, enc, BuildRequestCallback ); CallbackHelper.CheckResult(result); return(taskCompletionSource.Task); }
/// <summary> /// Revokes a user identified by a revoc_id in a given revoc-registry. /// </summary> /// <remarks> /// <para> /// The corresponding claim definition and revocation registry must be already /// have been created and stored in the wallet. /// </para> /// </remarks> /// <param name="wallet">The target wallet.</param> /// <param name="issuerDid">The DID of the issuer.</param> /// <param name="schemaSequenceNumber">The sequence number of the schema.</param> /// <param name="userRevocIndex">index of the user in the revocation registry</param> /// <returns>An asynchronous <see cref="Task{T}"/> that, when the operation completes, resolves /// to a revocation registry update JSON with a revoked claim.</returns> public static Task <string> IssuerRevokeClaimAsync(Wallet wallet, string issuerDid, int schemaSequenceNumber, int userRevocIndex) { ParamGuard.NotNull(wallet, "wallet"); ParamGuard.NotNullOrWhiteSpace(issuerDid, "issuerDid"); var taskCompletionSource = new TaskCompletionSource <string>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var commandResult = NativeMethods.indy_issuer_revoke_claim( commandHandle, wallet.Handle, issuerDid, schemaSequenceNumber, userRevocIndex, IssuerRevokeClaimCallback ); CallbackHelper.CheckResult(commandResult); return(taskCompletionSource.Task); }
/// <summary> /// Verifies a signature created by a key associated with the specified DID. /// </summary> /// <remarks> /// <para>If the wallet specified in the <paramref name="wallet"/> parameter contains a /// verkey associated with the DID provided in the <paramref name="did"/> parameter and the /// value has not expired this verkey will be used to verify the signature. /// </para> /// <para>On the other hand, if the verkey value in the wallet has expired or the verkey was not /// stored in the wallet then the verkey is read from the ledger in the node pool specified in the /// <paramref name="pool"/> parameter and the wallet will be updated with the new verkey if required. /// </para> /// <para>For further information on registering a verkey for a DID see the <see cref="StoreTheirDidAsync(Wallet, string)"/> /// method and for information on the expiry of values in a wallet see the /// <see cref="Wallet.CreateWalletAsync(string, string, string, string, string)"/> /// and <see cref="Wallet.OpenWalletAsync(string, string, string)"/> methods. /// </para> /// </remarks> /// <param name="wallet">The wallet containing the DID of the signed message.</param> /// <param name="pool">The node pool to obtain the verkey from if required.</param> /// <param name="did">The DID used to sign the message.</param> /// <param name="msg">The message that was signed.</param> /// <param name="signature">The signature to verify.</param> /// <returns>An asynchronous <see cref="Task{T}"/> that resolves to true if the message is valid, otherwise false.</returns> public static Task <bool> VerifySignatureAsync(Wallet wallet, Pool pool, string did, byte[] msg, byte[] signature) { var taskCompletionSource = new TaskCompletionSource <bool>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var commandResult = IndyNativeMethods.indy_verify_signature( commandHandle, wallet.Handle, pool.Handle, did, msg, msg.Length, signature, signature.Length, _verifySignatureCallback ); CallbackHelper.CheckResult(commandResult); return(taskCompletionSource.Task); }
/// <summary> /// Creates a new secure wallet and then imports its content /// according to fields provided in import_config /// This can be seen as an <see cref="CreateWalletAsync(string, string)"/> call with additional content import /// /// Note this endpoint is EXPERIMENTAL. Function signature and behaviour may change /// in the future releases. /// </summary> /// <returns>The async.</returns> /// <param name="config"> /// Wallet configuration json. /// <code> /// { /// "id": string, Identifier of the wallet. /// Configured storage uses this identifier to lookup exact wallet data placement. /// "storage_type": optional<string>, Type of the wallet storage. Defaults to 'default'. /// 'Default' storage type allows to store wallet data in the local file. /// Custom storage types can be registered with indy_register_wallet_storage call. /// "storage_config": optional<object>, Storage configuration json. Storage type defines set of supported keys. /// Can be optional if storage supports default configuration. /// For 'default' storage type configuration is: /// { /// "path": optional<string>, Path to the directory with wallet files. /// Defaults to $HOME/.indy_client/wallet. /// Wallet will be stored in the file {path}/{id}/sqlite.db /// } /// } /// </code> /// </param> /// <param name="credentials">Wallet credentials json /// <code> /// { /// "key": string, Passphrase used to derive wallet master key /// "storage_credentials": optional<object> Credentials for wallet storage. Storage type defines set of supported keys. /// Can be optional if storage supports default configuration. /// For 'default' storage type should be empty. /// /// } /// </code> /// </param> /// <param name="importConfig"> /// Import settings json. /// <code> /// { /// "path": <string>, path of the file that contains exported wallet content /// "key": <string>, passphrase used to derive export key /// } /// </code> /// </param> public static Task ImportAsync(string config, string credentials, string importConfig) { ParamGuard.NotNullOrWhiteSpace(config, "config"); ParamGuard.NotNullOrWhiteSpace(credentials, "credentials"); ParamGuard.NotNullOrWhiteSpace(importConfig, "importConfig"); var taskCompletionSource = new TaskCompletionSource <bool>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var result = NativeMethods.indy_import_wallet( commandHandle, config, credentials, importConfig, CallbackHelper.TaskCompletingNoValueCallback ); CallbackHelper.CheckResult(result); return(taskCompletionSource.Task); }
/// <summary> /// Builds a NODE ledger request. /// </summary> /// <param name="submitterDid">The DID of the submitter.</param> /// <param name="targetDid">The target DID.</param> /// <param name="data">id of a target NYM record</param> /// <returns>An asynchronous <see cref="Task{T}"/> that resolves to a <see cref="string"/> /// containing the request JSON. </returns> public static Task <string> BuildNodeRequestAsync(string submitterDid, string targetDid, string data) { ParamGuard.NotNullOrWhiteSpace(submitterDid, "submitterDid"); ParamGuard.NotNullOrWhiteSpace(targetDid, "targetDid"); ParamGuard.NotNullOrWhiteSpace(data, "data"); var taskCompletionSource = new TaskCompletionSource <string>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var result = NativeMethods.indy_build_node_request( commandHandle, submitterDid, targetDid, data, _buildRequestCallback ); CallbackHelper.CheckResult(result); return(taskCompletionSource.Task); }
/// <summary> /// Decrypts the provided message using the public key associated with my DID. /// </summary> /// <remarks> /// <para> /// The DID specified in the <paramref name="myDid"/> parameter must have been previously created /// with a secret key and stored in the wallet specified in the <paramref name="wallet"/> parameter. /// </para> /// <para> /// For further information on storing a DID and its secret key see the /// <see cref="CreateAndStoreMyDidAsync(Wallet, string)"/> method. /// </para> /// </remarks> /// <param name="wallet">The wallet containing the DID and associated secret key to use for decryption.</param> /// <param name="myDid">The DID to use for decryption.</param> /// <param name="did">The DID of the encrypting party to use for verification.</param> /// <param name="encryptedMsg">The message to decrypt.</param> /// <param name="nonce">The nonce used to encrypt the message.</param> /// <returns>An asynchronous <see cref="Task{T}"/> that resolves to a byte array containing the decrypted message.</returns> public static Task <byte[]> DecryptAsync(Wallet wallet, string myDid, string did, byte[] encryptedMsg, byte[] nonce) { var taskCompletionSource = new TaskCompletionSource <byte[]>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var commandResult = IndyNativeMethods.indy_decrypt( commandHandle, wallet.Handle, myDid, did, encryptedMsg, encryptedMsg.Length, nonce, nonce.Length, _decryptCallback ); CallbackHelper.CheckResult(commandResult); return(taskCompletionSource.Task); }
/// <summary> /// Creates a new pairwise record between two specified DIDs in the provided wallet. /// </summary> /// <param name="wallet">The wallet to store create the pairwise record in.</param> /// <param name="theirDid">The DID of the remote party.</param> /// <param name="myDid">The DID belonging to the owner of the wallet.</param> /// <param name="metadata">Optional metadata to store with the record.</param> /// <returns>An asynchronous <see cref="Task"/> completes once the operation completes.</returns> public static Task CreateAsync(Wallet wallet, string theirDid, string myDid, string metadata) { ParamGuard.NotNull(wallet, "wallet"); ParamGuard.NotNullOrWhiteSpace(theirDid, "theirDid"); ParamGuard.NotNullOrWhiteSpace(myDid, "myDid"); var taskCompletionSource = new TaskCompletionSource <bool>(); var commandHandle = PendingCommands.Add(taskCompletionSource); int result = NativeMethods.indy_create_pairwise( commandHandle, wallet.Handle, theirDid, myDid, metadata, CallbackHelper.TaskCompletingNoValueCallback); CallbackHelper.CheckResult(result); return(taskCompletionSource.Task); }
/// <summary> /// Creates a new revocation registry for the provided claim definition. /// </summary> /// <remarks> /// The revocation registry is stored in the provided <paramref name="wallet"/> and is identified by /// a unique key which is returned in the revocation registry JSON string returned by the method. /// </remarks> /// <param name="wallet">The wallet to store the revocation registry in.</param> /// <param name="issuerDid">The DID of the issuer that signed the revoc_reg transaction to the ledger.</param> /// <param name="schemaSeqNo">The sequence number of a schema transaction in the ledger.</param> /// <param name="maxClaimNum">The maximum number of claims the new registry can process.</param> /// <returns>An asynchronous <see cref="Task{T}"/> that, when the operation completes, resolves /// to a JSON string containing the revocation registry.</returns> public static Task <string> IssuerCreateAndStoreRevocRegAsync(Wallet wallet, string issuerDid, int schemaSeqNo, int maxClaimNum) { ParamGuard.NotNull(wallet, "wallet"); ParamGuard.NotNullOrWhiteSpace(issuerDid, "issuerDid"); var taskCompletionSource = new TaskCompletionSource <string>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var commandResult = NativeMethods.indy_issuer_create_and_store_revoc_reg( commandHandle, wallet.Handle, issuerDid, schemaSeqNo, maxClaimNum, _issuerCreateAndStoreClaimRevocRegCallback ); CallbackHelper.CheckResult(commandResult); return(taskCompletionSource.Task); }
/// <summary> /// Builds Indy request for setting fees for transactions in the ledger /// /// Note this endpoint is EXPERIMENTAL. Function signature and behaviour may change /// in the future releases. /// </summary> /// <returns>Indy request for setting fees for transactions in the ledger</returns> /// <param name="wallet">Wallet.</param> /// <param name="submitterDid">Submitter did.</param> /// <param name="paymentMethod">Payment method.</param> /// <param name="feesJson">Fees json. /// { /// txnType1: amount1, /// txnType2: amount2, /// ................. /// txnTypeN: amountN, /// }</param> public static Task <string> BuildSetTxnFeesRequestAsync(Wallet wallet, string submitterDid, string paymentMethod, string feesJson) { ParamGuard.NotNull(wallet, "wallet"); ParamGuard.NotNullOrWhiteSpace(paymentMethod, "paymentMethod"); ParamGuard.NotNullOrWhiteSpace(feesJson, "feesJson"); var taskCompletionSource = new TaskCompletionSource <string>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var result = NativeMethods.indy_build_set_txn_fees_req( commandHandle, wallet.Handle, submitterDid, paymentMethod, feesJson, BuildSetTxnFeesReqCallback); CallbackHelper.CheckResult(result); return(taskCompletionSource.Task); }
/// <summary> /// Signs a message with a payment address. /// </summary> /// <param name="wallet">Wallet handle</param> /// <param name="address">Payment address of message signer. The key must be created by calling <see cref="CreatePaymentAddressAsync" /></param> /// <param name="message">Message to be signed</param> /// <returns></returns> public static Task <byte[]> SignWithAddressAsync(Wallet wallet, string address, byte[] message) { ParamGuard.NotNullOrWhiteSpace(address, "address"); ParamGuard.NotNull(message, "message"); ParamGuard.NotNull(wallet, "wallet"); var taskCompletionSource = new TaskCompletionSource <byte[]>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var result = NativeMethods.indy_sign_with_address( commandHandle, wallet.Handle, address, message, (uint)message.Length, SignWithAddressDelegate); CallbackHelper.CheckResult(result); return(taskCompletionSource.Task); }
/// <summary> /// Prepare payment extra JSON with TAA acceptance data /// /// EXPERIMENTAL /// /// This function may calculate digest by itself or consume it as a parameter. /// If all text, version and taa_digest parameters are specified, a check integrity of them will be done. /// </summary> /// <param name="extra_json">(optional) original extra json.</param> /// <param name="text"> /// text and version - (optional) raw data about TAA from ledger. /// These parameters should be passed together. /// These parameters are required if taa_digest parameter is omitted. /// </param> /// <param name="version"> /// text and version - (optional) raw data about TAA from ledger. /// These parameters should be passed together. /// These parameters are required if taa_digest parameter is omitted. /// </param> /// <param name="taa_digest">(optional) digest on text and version. This parameter is required if text and version parameters are omitted.</param> /// <param name="mechanism">mechanism how user has accepted the TAA</param> /// <param name="time">UTC timestamp when user has accepted the TAA</param> /// <returns>Updated request result as json.</returns> public static Task <string> PreparePaymentExtraWithAcceptanceDataAsync(string extra_json, string text, string version, string taa_digest, string mechanism, ulong time) { ParamGuard.NotNullOrWhiteSpace(mechanism, "mechanism"); var taskCompletionSource = new TaskCompletionSource <string>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var result = NativeMethods.indy_prepare_payment_extra_with_acceptance_data( commandHandle, extra_json, text, version, taa_digest, mechanism, time, PreparePaymentExtraWithAcceptanceDataCallback); CallbackHelper.CheckResult(result); return(taskCompletionSource.Task); }
/// <summary> /// Modifies Indy request by adding information how to pay fees for this transaction /// according to selected payment method. /// /// Payment selection is performed by looking to o /// /// This method consumes set of UTXO inputs and outputs. The difference between inputs balance /// and outputs balance is the fee for this transaction. /// /// Not that this method also produces correct fee signatures. /// /// Format of inputs is specific for payment method. Usually it should reference payment transaction /// with at least one output that corresponds to payment address that user owns. /// /// Note this endpoint is EXPERIMENTAL. Function signature and behaviour may change /// in the future releases. /// </summary> /// <returns>The request fees async.</returns> /// <param name="wallet">Wallet.</param> /// <param name="submitterDid">DID of request sender</param> /// <param name="reqJson">Initial transaction request as json</param> /// <param name="inputsJson">The list of UTXO inputs as json array: /// ["input1", ...] /// Notes: /// - each input should reference paymentAddress /// - this param will be used to determine payment_method /// </param> /// <param name="outputsJson">outputs_json: The list of UTXO outputs as json array: /// [{ /// paymentAddress: <str>, // payment address used as output /// amount: <int>, // amount of tokens to transfer to this payment address /// extra: <str>, // optional data /// }]</param> /// <param name="extra">Optional information for payment operation.</param> public static Task <PaymentResult> AddRequestFeesAsync(Wallet wallet, string submitterDid, string reqJson, string inputsJson, string outputsJson, string extra) { ParamGuard.NotNull(wallet, "wallet"); var taskCompletionSource = new TaskCompletionSource <PaymentResult>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var result = NativeMethods.indy_add_request_fees( commandHandle, wallet.Handle, submitterDid, reqJson, inputsJson, outputsJson, extra, AddRequestFeesCallback); CallbackHelper.CheckResult(result); return(taskCompletionSource.Task); }
/// <summary> /// Builds a REVOC_REG_ENTRY request. Request to add the RevocReg entry containing /// the new accumulator value and issued/revoked indices. /// This is just a delta of indices, not the whole list. /// So, it can be sent each time a new credential is issued/revoked. /// </summary> /// <returns>The revoc reg entry request async.</returns> /// <param name="submitterDid">DID of the submitter stored in secured Wallet.</param> /// <param name="revocRegDefId">ID of the corresponding RevocRegDef.</param> /// <param name="revDefType">Revocation Registry type (only CL_ACCUM is supported for now).</param> /// <param name="value"> /// Registry-specific data: { /// value: { /// prevAccum: string - previous accumulator value. /// accum: string - current accumulator value. /// issued: array<number> - an array of issued indices. /// revoked: array<number> an array of revoked indices. /// }, /// ver: string - version revocation registry entry json /// /// }.</param> public static Task <string> BuildRevocRegEntryRequestAsync(string submitterDid, string revocRegDefId, string revDefType, string value) { ParamGuard.NotNullOrWhiteSpace(submitterDid, "submitterDid"); ParamGuard.NotNullOrWhiteSpace(revocRegDefId, "revocRegDefId"); ParamGuard.NotNullOrWhiteSpace(revDefType, "revDefType"); var taskCompletionSource = new TaskCompletionSource <string>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var result = NativeMethods.indy_build_revoc_reg_entry_request( commandHandle, submitterDid, revocRegDefId, revDefType, value, _buildRequestCallback); CallbackHelper.CheckResult(result); return(taskCompletionSource.Task); }
/// <summary> /// Signs the provided message using the specified DID. /// </summary> /// <remarks> /// The DID specified in the <paramref name="did"/> parameter must already be stored /// in the <see cref="Wallet"/> specified in the <paramref name="wallet"/> parameter /// with a signing key in order to be able to sign a message. See the /// <see cref="CreateAndStoreMyDidAsync(Wallet, string)"/> method for details. /// </remarks> /// <param name="wallet">The wallet that contains the DID.</param> /// <param name="did">The DID to sign with.</param> /// <param name="msg">The message to sign.</param> /// <returns>An asynchronous <see cref="Task{T}"/> that resolves to a byte array that contains signed message when signing is complete.</returns> public static Task <byte[]> SignAsync(Wallet wallet, string did, byte[] msg) { ParamGuard.NotNull(wallet, "wallet"); ParamGuard.NotNullOrWhiteSpace(did, "did"); ParamGuard.NotNull(msg, "msg"); var taskCompletionSource = new TaskCompletionSource <byte[]>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var commandResult = NativeMethods.indy_sign( commandHandle, wallet.Handle, did, msg, msg.Length, _signCallback ); CallbackHelper.CheckResult(commandResult); return(taskCompletionSource.Task); }
/// <summary> /// Builds a GET_CLAIM_DEF ledger request. /// </summary> /// <remarks> /// Builds a request message that is suitable for getting a claim definition from a ledger. /// </remarks> /// <note type="note">The <paramref name="signatureType"/> parameter only accepts the value /// 'CL' at present.</note> /// <param name="submitterDid">The DID of the party that will submit the request.</param> /// <param name="xref">The sequence number of the schema the claim definition targets.</param> /// <param name="signatureType">The type of signature used in the claim definition.</param> /// <param name="origin">The DID of the issuer of the claim definition.</param> /// <returns>An asynchronous <see cref="Task{T}"/> that resolves to a <see cref="string"/> /// containing the request JSON. </returns> public static Task <string> BuildGetClaimDefTxnAsync(string submitterDid, int xref, string signatureType, string origin) { ParamGuard.NotNullOrWhiteSpace(submitterDid, "submitterDid"); ParamGuard.NotNullOrWhiteSpace(signatureType, "signatureType"); ParamGuard.NotNullOrWhiteSpace(origin, "origin"); var taskCompletionSource = new TaskCompletionSource <string>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var result = IndyNativeMethods.indy_build_get_claim_def_txn( commandHandle, submitterDid, xref, signatureType, origin, _buildRequestCallback ); CallbackHelper.CheckResult(result); return(taskCompletionSource.Task); }
/// <summary> /// Signs the provided claim for using the key provided in the specified claim request. /// </summary> /// <remarks> /// <para> /// The <paramref name="claimReqJson"/> parameter must be passed a claim request that was previously /// created using the <see cref="ProverCreateAndStoreClaimReqAsync(Wallet, string, string, string, string)"/> /// method. Usually the claim request will be received from another party that has performed this /// action. /// </para> /// <para> /// The claim to be signed is provided in the <paramref name="claimJson"/> parameter /// and the structure of the claim must conform to the schema from claim request provided in /// the <paramref name="claimReqJson"/> parameter. Claims must be structured as a series of /// attributes, each of which has two values; a human readable value and a hex encoded value. /// <code> /// { /// "attr1" : ["value1", "value1_as_int"], /// "attr2" : ["value2", "value2_as_int"] /// } /// </code> /// For example: /// <code> /// { /// 'name': ['Alex', '1139481716457488690172217916278103335'], /// 'height': ['175', '175'] /// } /// </code> /// </para> /// <para> /// This method results a revocation registry update JSON and a newly issued claim JSON. The /// claim JSON contains the issued claim, the DID of the issuer (<c>issuer_did</c>), /// schema sequence number (<c>schema_seq_no</c>) and revocation registry sequence number (<c> /// revoc_reg_seq_no</c>) used for issuance: /// <code> /// { /// "claim": <see claim_json above>, /// "signature": <signature>, /// "revoc_reg_seq_no", string, /// "issuer_did", string, /// "schema_seq_no", string, /// } /// </code> /// </para> /// </remarks> /// <param name="wallet">The wallet containing the keys to use for signing the claim.</param> /// <param name="claimReqJson">A claim request with a blinded secret.</param> /// <param name="claimJson">A claim containing attribute values for each of requested attribute names.</param> /// <param name="userRevocIndex">The index of a new user in the revocation registry or -1 if absentee.</param> /// <returns>An asynchronous <see cref="Task{T}"/> that, when the operation completes, resolves to /// an <see cref="IssuerCreateClaimResult"/>.</returns> public static Task <IssuerCreateClaimResult> IssuerCreateClaimAsync(Wallet wallet, string claimReqJson, string claimJson, int userRevocIndex) { ParamGuard.NotNull(wallet, "wallet"); ParamGuard.NotNullOrWhiteSpace(claimReqJson, "claimReqJson"); ParamGuard.NotNullOrWhiteSpace(claimJson, "claimJson"); var taskCompletionSource = new TaskCompletionSource <IssuerCreateClaimResult>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var commandResult = NativeMethods.indy_issuer_create_claim( commandHandle, wallet.Handle, claimReqJson, claimJson, userRevocIndex, _issuerCreateClaimCallback ); CallbackHelper.CheckResult(commandResult); return(taskCompletionSource.Task); }
/// <summary> /// Verify a signature with a payment address. /// </summary> /// <param name="address">Payment address of the message signer</param> /// <param name="message">Message data</param> /// <param name="signature">Signed message data</param> /// <returns><c>true</c> - if signature is valid, <c>false</c> - otherwise</returns> public static Task <bool> VerifyWithAddressAsync(string address, byte[] message, byte[] signature) { ParamGuard.NotNullOrWhiteSpace(address, "address"); ParamGuard.NotNull(message, "message"); ParamGuard.NotNull(signature, "signature"); var taskCompletionSource = new TaskCompletionSource <bool>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var result = NativeMethods.indy_verify_with_address( commandHandle, address, message, (uint)message.Length, signature, (uint)signature.Length, VerifyWithAddressDelegate); CallbackHelper.CheckResult(result); return(taskCompletionSource.Task); }
/// <summary> /// Decrypts the provided message using the public key associated with the specified DID using the anonymous-encryption scheme. /// </summary> /// <param name="wallet">The wallet containing the DID and associated secret key to use for decryption.</param> /// <param name="did">The DID of the encrypting party to use for verification.</param> /// <param name="encryptedMsg">The message to decrypt.</param> /// <returns>An asynchronous <see cref="Task{T}"/> that resolves to a byte array containing the decrypted message.</returns> public static Task <byte[]> DecryptSealedAsync(Wallet wallet, string did, byte[] encryptedMsg) { ParamGuard.NotNull(wallet, "wallet"); ParamGuard.NotNullOrWhiteSpace(did, "did"); ParamGuard.NotNull(encryptedMsg, "encryptedMsg"); var taskCompletionSource = new TaskCompletionSource <byte[]>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var commandResult = NativeMethods.indy_decrypt_sealed( commandHandle, wallet.Handle, did, encryptedMsg, encryptedMsg.Length, _decryptSealedCallback ); CallbackHelper.CheckResult(commandResult); return(taskCompletionSource.Task); }
/// <summary> /// Builds a ledger request to store a NYM. /// </summary> /// <remarks> /// <para> /// Builds a request message that is suitable for storing a NYM for the <paramref name="targetDid"/> /// on the ledger. /// </para> /// <para> /// Only the <paramref name="submitterDid"/> and <paramref name="targetDid"/> parameters /// are required, however the other parameters provide greater control over the process. Normally /// the <paramref name="targetDid"/> and <paramref name="verKey"/> parameters would be from values /// generated by a prior call to <see cref="Signus.CreateAndStoreMyDidAsync(Wallet, string)"/>. /// </para> /// <para> /// The <paramref name="role"/> parameter dictates what permissions the NYM will have - valid values /// are 'STEWARD' and 'TRUSTEE' and 'TRUST_ANCHOR'. /// </para> /// </remarks> /// <param name="submitterDid">The DID of the party who will submit the request to the ledger.</param> /// <param name="targetDid">The DID the NYM belongs to.</param> /// <param name="verKey">The verification key for the NYM.</param> /// <param name="alias">The alias for the NYM.</param> /// <param name="role">The role of the NYM.</param> /// <returns>An asynchronous <see cref="Task{T}"/> that resolves to a <see cref="string"/> /// containing the request JSON. </returns> public static Task <string> BuildNymRequestAsync(string submitterDid, string targetDid, string verKey, string alias, string role) { ParamGuard.NotNullOrWhiteSpace(submitterDid, "submitterDid"); ParamGuard.NotNullOrWhiteSpace(targetDid, "targetDid"); var taskCompletionSource = new TaskCompletionSource <string>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var result = IndyNativeMethods.indy_build_nym_request( commandHandle, submitterDid, targetDid, verKey, alias, role, _buildRequestCallback ); CallbackHelper.CheckResult(result); return(taskCompletionSource.Task); }
/// <summary> /// Packs a message (Experimental) /// /// Note to use DID keys with this function you can call indy_key_for_did to get key id (verkey) /// for specific DID. /// </summary> /// <param name="wallet">The wallet containing the key-pair associated with the verification key specified in the <paramref name="recipientVk"/> parameter.</param> /// <param name="recipientVk">A string in the format of a json list which will contain the list of receiver's keys /// the message is being encrypted for. /// Example: /// <code>[<receiver edge_agent_1 verkey>, <receiver edge_agent_2 verkey>]</code> /// </param> /// <param name="senderVk">The sender's verkey as a string or null. /// <remarks>When null pointer is used in this parameter, anoncrypt is used</remarks> /// </param> /// <param name="message">The message data to pack.</param> /// <returns>a JWE using authcrypt alg is defined below: /// <code> /// { /// "protected": "b64URLencoded({ /// "enc": "xsalsa20poly1305", /// "typ": "JWM/1.0", /// "alg": "Authcrypt", /// "recipients": [ /// { /// "encrypted_key": base64URLencode(libsodium.crypto_box(my_key, their_vk, cek, cek_iv)) /// "header": { /// "kid": "base58encode(recipient_verkey)", /// "sender" : base64URLencode(libsodium.crypto_box_seal(their_vk, base58encode(sender_vk)), /// "iv" : base64URLencode(cek_iv) /// } /// }, /// ], /// })", /// "iv": <b64URLencode(iv)>, /// "ciphertext": b64URLencode(encrypt_detached({'@type'...}, protected_value_encoded, iv, cek), /// "tag": <b64URLencode(tag)> /// } /// </code> /// Alternative example in using anoncrypt alg is defined below: /// <code> /// { /// "protected": "b64URLencoded({ /// "enc": "xsalsa20poly1305", /// "typ": "JWM/1.0", /// "alg": "Anoncrypt", /// "recipients": [ /// { /// "encrypted_key": base64URLencode(libsodium.crypto_box_seal(their_vk, cek)), /// "header": { /// "kid": base58encode(recipient_verkey), /// } /// }, /// ], /// })", /// "iv": b64URLencode(iv), /// "ciphertext": b64URLencode(encrypt_detached({'@type'...}, protected_value_encoded, iv, cek), /// "tag": b64URLencode(tag) /// } /// </code> /// </returns> public static Task <byte[]> PackMessageAsync(IWallet wallet, string recipientVk, string senderVk, byte[] message) { ParamGuard.NotNull(wallet, "wallet"); ParamGuard.NotNullOrWhiteSpace(recipientVk, "recipientVk"); ParamGuard.NotNull(message, "message"); var taskCompletionSource = new TaskCompletionSource <byte[]>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var commandResult = NativeMethods.indy_pack_message( commandHandle, (int)wallet.Handle, message, message.Length, recipientVk, senderVk, PackMessageCompletedCallback); CallbackHelper.CheckResult(commandResult); return(taskCompletionSource.Task); }
/// <summary> /// Decrypts a message encrypted using an anonymous-encryption scheme /// </summary> /// <remarks> /// <para> /// Sealed boxes are designed to a <c>sender</c> to anonymously send messages to a <c>recipient</c> using the /// recipient's public key. /// Only the recipient can decrypt these messages, using their private key. /// While the recipient can verify the integrity of the message, they cannot verify the identity of the sender. /// </para> /// <note type="note"> /// To use DID keys with this method call the <see cref="Did.KeyForDidAsync(PoolApi.Pool, Wallet, string)"/> with the desired DID to get /// its verification key which can be used as the <paramref name="myVk"/> parameter when calling this method. /// </note> /// </remarks> /// <param name="wallet">The wallet containing the key-pair associated with the verification key specified in the <paramref name="myVk"/> parameter.</param> /// <param name="myVk">The verification key of the intended recipient of the encrypted message.</param> /// <param name="encryptedMessage">The encrypted message to decrypt.</param> /// <returns>An asynchronous <see cref="Task{T}"/> that resolves to a byte array containing the decrypted message.</returns> /// <exception cref="WalletValueNotFoundException">Thrown if <paramref name="myVk"/> is not present in the <paramref name="wallet"/>.</exception> /// <exception cref="InvalidStructureException">Thrown if <paramref name="myVk"/> was not used to encrypt <paramref name="encryptedMessage"/>.</exception> public static Task <byte[]> AnonDecryptAsync(Wallet wallet, string myVk, byte[] encryptedMessage) { ParamGuard.NotNull(wallet, "wallet"); ParamGuard.NotNullOrWhiteSpace(myVk, "myVk"); ParamGuard.NotNull(encryptedMessage, "encryptedMessage"); var taskCompletionSource = new TaskCompletionSource <byte[]>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var commandResult = NativeMethods.indy_crypto_anon_decrypt( commandHandle, wallet.Handle, myVk, encryptedMessage, encryptedMessage.Length, _cryptoAnonDecryptCompletedCallback ); CallbackHelper.CheckResult(commandResult); return(taskCompletionSource.Task); }
/// <summary> /// Decrypt a message by authenticated-encryption scheme. /// /// Sender can encrypt a confidential message specifically for Recipient, using Sender's public key. /// Using Recipient's public key, Sender can compute a shared secret key. /// Using Sender's public key and his secret key, Recipient can compute the exact same shared secret key. /// That shared secret key can be used to verify that the encrypted message was not tampered with, /// before eventually decrypting it. /// </summary> /// <remarks> /// Note to use DID keys with this function you can call indy_key_for_did to get key id (verkey) /// for specific DID. /// </remarks> /// <returns>sender verkey and decrypted message</returns> /// <param name="wallet">The wallet containing the key-pair to sign with.</param> /// <param name="myVk">id (verkey) of my key. The key must be created by calling indy_create_key or indy_create_and_store_my_did</param> /// <param name="message">The message data to be decrypted.</param> public static Task <AuthDecryptResult> AuthDecryptAsync(IWallet wallet, string myVk, byte[] message) { ParamGuard.NotNull(wallet, "wallet"); ParamGuard.NotNullOrWhiteSpace(myVk, "myVk"); ParamGuard.NotNull(message, "message"); var taskCompletionSource = new TaskCompletionSource <AuthDecryptResult>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var commandResult = NativeMethods.indy_crypto_auth_decrypt( commandHandle, (int)wallet.Handle, myVk, message, message.Length, CryptoAuthDecryptCompletedCallback ); CallbackHelper.CheckResult(commandResult); return(taskCompletionSource.Task); }
/// <summary> /// Adds an identity to the listener. /// </summary> /// <remarks> /// <para>Although an AgentListner instance can listen for incoming connections on a specified /// endpoint, any incoming connection to an identity not associated with the listener will be /// automatically rejected. This method adds an identity to the listener that will be authorized /// to accept connections. /// </para> /// <para>This method will perform a <see cref="Wallet"/> lookup to find the identity information /// for the DID to add and consequently the DID must have already been saved in the wallet using /// the <see cref="Hyperledger.Indy.SignusApi.CreateAndStoreMyDidResult"/> method prior to attempting to /// add it to the listener. /// </para> /// <para>Authorization to accept incoming connections to a DID on a listener can be removed using /// the <see cref="RemoveIdentityAsync(Wallet, string)"/> method. /// </para> /// </remarks> /// <seealso cref="Signus"/> /// <param name="pool">The node pool that will be used to verify the identity.</param> /// <param name="wallet">The Wallet that contains the identity.</param> /// <param name="did">The DID of the identity to authorize connections to.</param> /// <returns>An asynchronous <see cref="Task"/> completes once the operation completes.</returns> public Task AddIdentityAsync(Pool pool, Wallet wallet, string did) { ParamGuard.NotNull(pool, "pool"); ParamGuard.NotNull(wallet, "wallet"); ParamGuard.NotNullOrWhiteSpace(did, "did"); var taskCompletionSource = new TaskCompletionSource <bool>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var result = IndyNativeMethods.indy_agent_add_identity( commandHandle, Handle, pool.Handle, wallet.Handle, did, CallbackHelper.TaskCompletingNoValueCallback ); CallbackHelper.CheckResult(result); return(taskCompletionSource.Task); }
/// <summary> /// Sets the endpoint details for the specified DID. /// </summary> /// <param name="wallet">The wallet containing the DID.</param> /// <param name="did">The DID to set the endpoint details on.</param> /// <param name="address">The address of the endpoint.</param> /// <param name="transportKey">The transport key.</param> /// <returns>An asynchronous <see cref="Task"/> that completes when the operation completes.</returns> /// <exception cref="InvalidStructureException">Thrown if the <paramref name="did"/> or <paramref name="transportKey"/> values are malformed.</exception> public static Task SetEndpointForDidAsync(Wallet wallet, string did, string address, string transportKey) { ParamGuard.NotNull(wallet, "wallet"); ParamGuard.NotNullOrWhiteSpace(did, "did"); ParamGuard.NotNullOrWhiteSpace(address, "address"); ParamGuard.NotNullOrWhiteSpace(transportKey, "transportKey"); var taskCompletionSource = new TaskCompletionSource <bool>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var commandResult = NativeMethods.indy_set_endpoint_for_did( commandHandle, wallet.Handle, did, address, transportKey, CallbackHelper.TaskCompletingNoValueCallback ); CallbackHelper.CheckResult(commandResult); return(taskCompletionSource.Task); }
/// <summary> /// Verifies a message signature with a verification key. /// </summary> /// <note type="note"> /// To use DID keys with this method call the <see cref="Did.KeyForDidAsync(PoolApi.Pool, Wallet, string)"/> with the desired DID to get /// its verification key which can be used as the <paramref name="theirVk"/> parameter when calling this method. /// </note> /// <param name="theirVk">The verification key belonging to the party that signed the message.</param> /// <param name="message">The message that was signed.</param> /// <param name="signature">The signature for the message.</param> /// <returns>An asynchronous <see cref="Task{T}"/> that, when the operation completes, resolves to true if the signature was valid, otherwise false.</returns> public static Task <bool> VerifyAsync(string theirVk, byte[] message, byte[] signature) { ParamGuard.NotNullOrWhiteSpace(theirVk, "theirVk"); ParamGuard.NotNull(message, "message"); ParamGuard.NotNull(signature, "signature"); var taskCompletionSource = new TaskCompletionSource <bool>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var commandResult = NativeMethods.indy_crypto_verify( commandHandle, theirVk, message, message.Length, signature, signature.Length, _cryptoVerifyCompletedCallback ); CallbackHelper.CheckResult(commandResult); return(taskCompletionSource.Task); }
/// <summary> /// Prepares a message so that it can be securely sent to a recipient. /// </summary> /// <param name="wallet">The wallet containing the keys of the sender and the recipient.</param> /// <param name="senderKey">The public key of the sender.</param> /// <param name="recipientKey">The verification key of the intended recipient of the message.</param> /// <param name="message">The message content to prepare.</param> /// <returns>An asynchronous <see cref="Task{T}"/> that resolves to an array of bytes containing the prepared message.</returns> /// <exception cref="WalletValueNotFoundException">Thrown if the sender key does not exist in the <paramref name="wallet"/>.</exception> /// <exception cref="InvalidStructureException">Thrown if the <paramref name="recipientKey"/> is invalid.</exception> public static Task <byte[]> PrepMsgAsync(Wallet wallet, string senderKey, string recipientKey, byte[] message) { ParamGuard.NotNull(wallet, "wallet"); ParamGuard.NotNullOrWhiteSpace(senderKey, "senderKey"); ParamGuard.NotNullOrWhiteSpace(recipientKey, "recipientKey"); ParamGuard.NotNull(message, "message"); var taskCompletionSource = new TaskCompletionSource <byte[]>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var result = NativeMethods.indy_prep_msg( commandHandle, wallet.Handle, senderKey, recipientKey, message, message.Length, _agentMessagePreparedCallback); CallbackHelper.CheckResult(result); return(taskCompletionSource.Task); }
/// <summary> /// Signs and submits a request to the validator pool. /// </summary> /// <remarks> /// This method adds information associated with the submitter specified by the /// <paramref name="submitterDid"/> to the JSON provided in the <paramref name="requestJson"/> parameter /// then signs it with the submitter's signing key from the provided <paramref name="wallet"/> and sends the signed /// request message to the specified validator <paramref name="pool"/>. /// </remarks> /// <param name="pool">The validator pool to submit the request to.</param> /// <param name="wallet">The wallet containing the submitter keys to sign the request with.</param> /// <param name="submitterDid">The DID of the submitter identity.</param> /// <param name="requestJson">The request JSON to sign and submit.</param> /// <returns>An asynchronous <see cref="Task{T}"/> that resolves to a JSON <see cref="string"/> /// containing the result of submission when the operation completes.</returns> public static Task <string> SignAndSubmitRequestAsync(Pool pool, Wallet wallet, string submitterDid, string requestJson) { ParamGuard.NotNull(pool, "pool"); ParamGuard.NotNull(wallet, "wallet"); ParamGuard.NotNullOrWhiteSpace(submitterDid, "submitterDid"); ParamGuard.NotNullOrWhiteSpace(requestJson, "requestJson"); var taskCompletionSource = new TaskCompletionSource <string>(); var commandHandle = PendingCommands.Add(taskCompletionSource); var result = NativeMethods.indy_sign_and_submit_request( commandHandle, pool.Handle, wallet.Handle, submitterDid, requestJson, SubmitRequestCallback ); CallbackHelper.CheckResult(result); return(taskCompletionSource.Task); }