Skip to content

Commit

Permalink
fix: updated documentation and examples (#562)
Browse files Browse the repository at this point in the history
Co-authored-by: Carlos Rincon <“carlos.r@affinidi.com”>
  • Loading branch information
carlos-affinidi and Carlos Rincon authored Feb 6, 2025
1 parent 9b77bd9 commit 54816c2
Show file tree
Hide file tree
Showing 34 changed files with 243 additions and 124 deletions.
6 changes: 3 additions & 3 deletions packages/dart/auth_provider/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ include: package:lints/recommended.yaml

# Uncomment the following section to specify additional rules.

# linter:
# rules:
# - camel_case_types
linter:
rules:
- public_member_api_docs

# analyzer:
# exclude:
Expand Down
33 changes: 0 additions & 33 deletions packages/dart/auth_provider/example/iota_token.dart

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import 'package:affinidi_tdk_auth_provider/affinidi_tdk_auth_provider.dart';
import 'package:dotenv/dotenv.dart';

void main() async {
final env = DotEnv(includePlatformEnvironment: true)..load();
var env = DotEnv()..load();
if (!env.isEveryDefined(['PROJECT_ID', 'TOKEN_ID', 'PRIVATE_KEY'])) {
print(
'Missing environment variables. Please provide PROJECT_ID, TOKEN_ID, PRIVATE_KEY');
'Missing variables. Please provide PROJECT_ID, TOKEN_ID and PRIVATE_KEY');
return;
}
// Workaround for dotenv multiline limitations
Expand All @@ -20,12 +20,27 @@ void main() async {
passphrase: env['PASSPHRASE'],
);

// Fetch project scoped token
try {
// Fetch project scoped token
final projectScopedToken = await provider.fetchProjectScopedToken();
print('Successfully obtained project scoped token:');
print(projectScopedToken);
} catch (e) {
print('Error obtaining token: $e');
}

// Fetch iota token (websocket).
// DID is usually obtained at runtime from the registered user
if (!env.isEveryDefined(['IOTA_CONFIG_ID', 'DID'])) {
print('Missing variables. Please provide IOTA_CONFIG_ID and DID');
return;
}
try {
final iotaToken = provider.createIotaToken(
iotaConfigId: env['IOTA_CONFIG_ID']!, did: env['DID']!);
print('Successfully obtained iota token:');
print(iotaToken);
} catch (e) {
print('Error obtaining token: $e');
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
/// Support for doing something awesome.
///
/// More dartdocs go here.
library;

export 'src/auth_provider.dart';

// TODO: Export any libraries intended for clients of this package.
29 changes: 28 additions & 1 deletion packages/dart/auth_provider/lib/src/auth_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,34 @@ import 'package:uuid/uuid.dart';
import 'iam_client.dart';
import 'jwt_helper.dart';

/// An authentication provider to make use of Affinidi services that require
/// project scoped tokens.
class AuthProvider {
/// The project ID of your Affinidi project.
final String projectId;

/// The ID of the Personal Access Token (PAT) registered with Affinidi.
final String tokenId;

/// The private key that was used when creating the PAT.
final String privateKey;

/// The key ID that was used when creating the PAT, if provided.
final String? keyId;

/// The passphrase that was used when creating the PAT, if provided.
final String? passphrase;

/// (Internal) The URL of the Affinidi API Gateway that you want to
/// authenticate against. Defaults to the production environment.
final String apiGatewayUrl;

/// (Internal) The URL of the Affinidi Elements Token Endpoint. Defaults to
/// the production environment.
final String tokenEndpoint;

/// Creates a new instance of the AuthProvider from the Personal Access Token
/// (PAT) that you have registered with Affinidi.
AuthProvider({
required this.projectId,
required this.tokenId,
Expand All @@ -26,6 +45,8 @@ class AuthProvider {
}) : apiGatewayUrl = Environment.fetchApiGwUrl(),
tokenEndpoint = Environment.fetchElementsAuthTokenUrl();

/// Constructor for internal use only. Allows for custom API Gateway and
/// token endpoint.
AuthProvider.withEnv({
required this.projectId,
required this.tokenId,
Expand Down Expand Up @@ -54,6 +75,9 @@ class AuthProvider {
}
}

/// Fetches a project scoped token from Affinidi Elements to be used for
/// API calls to Affinidi services. This function can be provided to clients
/// to authenticate their requests, allowing for token refresh after expiration.
Future<String> fetchProjectScopedToken() async {
if (await _shouldFetchToken()) {
_projectScopedToken =
Expand All @@ -68,7 +92,7 @@ class AuthProvider {
tokenId: tokenId,
privateKey: privateKey,
keyId: keyId,
passphrase: passphrase,
// passphrase: passphrase,
);

final response = await http.post(
Expand Down Expand Up @@ -114,6 +138,9 @@ class AuthProvider {
return data['accessToken'];
}

/// Generates an iota token to be used when setting up an iota websockets
/// connection. This token is only used when using iota with websockets,
/// and not when using iota through redirects.
({String iotaJwt, String iotaSessionId}) createIotaToken({
required String iotaConfigId,
required String did,
Expand Down
3 changes: 3 additions & 0 deletions packages/dart/auth_provider/lib/src/iam_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import 'dart:convert';

import 'package:http/http.dart' as http;

/// IAM Client for interacting with the IAM service.
class IamClient {
/// Creates a new instance of [IamClient].
IamClient({
required String apiGatewayUrl,
http.Client? httpClient,
Expand All @@ -12,6 +14,7 @@ class IamClient {
final http.Client _httpClient;
final String _apiGatewayUrl;

/// Fetches the public key from the IAM service.
Future<Map<String, dynamic>> getPublicKeyJWKS() async {
final response = await _httpClient.get(
Uri.parse('$_apiGatewayUrl/iam/.well-known/jwks.json'),
Expand Down
3 changes: 3 additions & 0 deletions packages/dart/auth_provider/lib/src/jwt_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import 'package:pointycastle/export.dart' as pce;

import 'iam_client.dart';

/// Helper class for creating and signing JWT tokens.
class JWTHelper {
/// Signs a payload with the given private key and returns the JWT token.
static String signPayload({
required String audience,
required String tokenId,
Expand Down Expand Up @@ -43,6 +45,7 @@ class JWTHelper {
return token;
}

/// Fetches the public key from the IAM client and returns it as an ECPublicKey.
static Future<ECPublicKey> fetchPublicKey(IamClient iamClient) async {
final jwk = await iamClient.getPublicKeyJWKS();
return ECPublicKey.raw(_jwkToPublicKey(jwk));
Expand Down
6 changes: 3 additions & 3 deletions packages/dart/common/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ analyzer:

# Uncomment the following section to specify additional rules.

# linter:
# rules:
# - camel_case_types
linter:
rules:
- public_member_api_docs

# analyzer:
# exclude:
Expand Down
30 changes: 0 additions & 30 deletions packages/dart/common/example/claim_credential_example.dart

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:affinidi_tdk_common/affinidi_tdk_common.dart';
import 'package:affinidi_tdk_auth_provider/affinidi_tdk_auth_provider.dart';
import 'package:affinidi_tdk_credential_issuance_client/affinidi_tdk_credential_issuance_client.dart';
import 'package:affinidi_tdk_iota_client/affinidi_tdk_iota_client.dart';

void main() async {
Expand All @@ -11,6 +12,35 @@ void main() async {
passphrase: '',
);

// Claim a credential Vault link example
final affinidiVaultClaimLink = await _claimCredentialExample(authProvider);
print(affinidiVaultClaimLink);

// Share a credential Vault link example
final affinidiVaultShareLink = await _shareCredentialExample(authProvider);
print(affinidiVaultShareLink);
}

Future<String> _claimCredentialExample(AuthProvider authProvider) async {
final issuanceClient = AffinidiTdkCredentialIssuanceClient(
authTokenHook: authProvider.fetchProjectScopedToken);
final issuanceApi = issuanceClient.getIssuanceApi();

final startIssuanceInputBuilder =
StartIssuanceInputBuilder(); // Add credential issuance data here

final offer = (await issuanceApi.startIssuance(
projectId: '', startIssuanceInput: startIssuanceInputBuilder.build()))
.data;

// Use the vault utilities from the common package to build the claim link
final affinidiVaultClaimLink =
VaultUtils.buildClaimLink(offer!.credentialOfferUri);

return affinidiVaultClaimLink;
}

Future<String> _shareCredentialExample(AuthProvider authProvider) async {
final iotaClient = AffinidiTdkIotaClient(
authTokenHook: authProvider.fetchProjectScopedToken);
final iotaApi = iotaClient.getIotaApi();
Expand All @@ -32,5 +62,5 @@ void main() async {
final affinidiVaultClaimLink =
VaultUtils.buildShareLink(iotaRequest!.data!.jwt, 'my_client_id');

print(affinidiVaultClaimLink);
return affinidiVaultClaimLink;
}
3 changes: 0 additions & 3 deletions packages/dart/common/lib/affinidi_tdk_common.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
/// Support for doing something awesome.
///
/// More dartdocs go here.
library;

export 'src/environment.dart';
Expand Down
Loading

0 comments on commit 54816c2

Please sign in to comment.