Skip to content

Commit 63288bf

Browse files
resolve review comments
1 parent ec4cfcc commit 63288bf

File tree

1 file changed

+57
-92
lines changed

1 file changed

+57
-92
lines changed

docs/keri/advanced/PublishExistingCredential.java

Lines changed: 57 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -57,37 +57,29 @@
5757

5858
public class PublishExistingCredential {
5959

60-
// ------- Constants ------- //
6160
private static final String REGISTRY_NAME = "CredentialRegistry";
62-
63-
// Required: Passcode from CreateRandomIdentifier.java
64-
private static final String IDENTIFIER_BRAN = System.getenv("IDENTIFIER_BRAN");
65-
66-
// Required: Identifier name from CreateRandomIdentifier.java
6761
private static final String IDENTIFIER_NAME = "GTReeveClient";
68-
62+
6963
public static final String QVI_SCHEMA_SAID = "EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao";
7064
public static final String LE_SCHEMA_SAID = "ENPXp1vQzRF6JwIuS-mp2U8Uf1MoADoP_GqQ62VsDZWY";
7165
private static final String VLEI_CARDANO_METADATA_SIGNER_SCHEMA_SAID = "EKU2UWx115nPv1JqWVMCFRn0_EMaME08HrUK5cLuTP89";
7266

7367
public static final String SCHEMA_SERVER_URL = "https://cred-issuance.demo.idw-sandboxes.cf-deployments.org/oobi";
74-
public static final String KERI_URL = "http://127.0.0.1:3901";
75-
public static final String KERI_BOOT_URL = "http://127.0.0.1:3903";
68+
public static final String KERI_URL = "https://keria.staging.cardano-foundation.app.reeve.technology";
69+
public static final String KERI_BOOT_URL = "https://keria-boot.staging.cardano-foundation.app.reeve.technology";
7670

77-
// Schemas
7871
public static final String VLEI_CARDANO_METADATA_SIGNER_SCHEMA_URL = SCHEMA_SERVER_URL + "/" + VLEI_CARDANO_METADATA_SIGNER_SCHEMA_SAID;
7972
public static final String LE_SCHEMA_URL = SCHEMA_SERVER_URL + "/" + LE_SCHEMA_SAID;
8073
public static final String QVI_SCHEMA_URL = SCHEMA_SERVER_URL + "/" + QVI_SCHEMA_SAID;
8174

82-
private static final String ISSUER_OOBI = System.getenv().getOrDefault("ISSUER_OOBI", "http://keria:3902/oobi/EPHDURdr576cf2HHjzqA68uqnTse0Pi7eMoDkBvr1-jw/agent/EBvTnpvK02atW3EYBbd4CRaEhzSe5a0V7_xREHxaHviB");
83-
84-
private static final String LEI = System.getenv().getOrDefault("LEI", "5493001KJTIIGC8Y1R12");
75+
private static final String passcode = System.getenv().getOrDefault("PASSCODE", "");
76+
private static final String LEI = System.getenv().getOrDefault("LEI", "");
8577

8678
// Wallet specific constants
87-
private static final String mnemonic = System.getenv().getOrDefault("MNEMONIC", "test test test test test test test test test test test test test test test test test test test test test test test sauce");
88-
private static final String NETWORK_TYPE = System.getenv().getOrDefault("NETWORK", "preview");
79+
private static final String mnemonic = System.getenv().getOrDefault("MNEMONIC", "");
80+
private static final String NETWORK_TYPE = System.getenv().getOrDefault("NETWORK", "mainnet");
8981
private static final Network network = getNetwork();
90-
private static final String BLOCKFROST_PROJECT_ID = System.getenv().getOrDefault("BLOCKFROST_PROJECT_ID", "dummy");
82+
private static final String blockfrostProjectId = System.getenv().getOrDefault("BLOCKFROST_PROJECT_ID", "");
9183
private static final BackendService backendService = createBackendService();
9284
private static final QuickTxBuilder QuickTxBuilder = new QuickTxBuilder(backendService);
9385

@@ -105,18 +97,26 @@ private static BackendService createBackendService() {
10597
case "preprod" -> "https://cardano-preprod.blockfrost.io/api/v0/";
10698
default -> "https://cardano-preview.blockfrost.io/api/v0/";
10799
};
108-
return new BFBackendService(baseUrl, BLOCKFROST_PROJECT_ID);
100+
return new BFBackendService(baseUrl, blockfrostProjectId);
109101
}
110102

111103
public static void main(String[] args) throws Exception {
112-
// Validate required environment variables
113-
if (IDENTIFIER_BRAN == null || IDENTIFIER_BRAN.isEmpty()) {
114-
System.err.println("ERROR: IDENTIFIER_BRAN environment variable is required.");
115-
System.exit(1);
116-
}
104+
Map<String, String> requiredEnvVars = Map.of(
105+
"PASSCODE", passcode,
106+
"LEI", LEI,
107+
"MNEMONIC", mnemonic,
108+
"BLOCKFROST_PROJECT_ID", blockfrostProjectId
109+
);
110+
111+
requiredEnvVars.forEach((name, value) -> {
112+
if (value == null || value.isEmpty()) {
113+
System.err.println("ERROR: " + name + " environment variable is required.");
114+
System.exit(1);
115+
}
116+
});
117117

118118
// --- SETUP CLIENT WITH EXISTING IDENTIFIER --- //
119-
SignifyClient client = KeriUtils.connectClient(KERI_URL, KERI_BOOT_URL, IDENTIFIER_BRAN);
119+
SignifyClient client = KeriUtils.connectClient(KERI_URL, KERI_BOOT_URL, passcode);
120120
KeriUtils.Aid aid = KeriUtils.getExistingAid(client, IDENTIFIER_NAME);
121121

122122
if (aid == null) {
@@ -129,53 +129,48 @@ public static void main(String[] args) throws Exception {
129129
System.out.println(" OOBI: " + aid.oobi());
130130
System.out.println();
131131

132-
// Create registry if it doesn't exist
133132
RegistryResult registry = createRegistry(client, aid, REGISTRY_NAME);
134133

135-
// Resolve schemas
136134
List<String> schemaUrls = List.of(QVI_SCHEMA_URL, LE_SCHEMA_URL, VLEI_CARDANO_METADATA_SIGNER_SCHEMA_URL);
137135
resolveSchemas(client, schemaUrls);
138-
139-
// Add issuer contact
140-
getOrCreateContact(client, "issuer", ISSUER_OOBI);
141136

142137
// Check if credential was already issued
143138
List<Map<String, Object>> existingCredentials = findIssuedCredential(client, aid.prefix(), VLEI_CARDANO_METADATA_SIGNER_SCHEMA_SAID);
144-
if (existingCredentials.size() > 0) {
145-
// Ask user if they want to push existing credential to chain
146-
System.out.print("\nDo you want to push the existing credential to the blockchain? (yes/no): ");
147-
String response = System.console() != null ? System.console().readLine() : new java.util.Scanner(System.in).nextLine();
148-
149-
if (response != null && (response.equalsIgnoreCase("yes") || response.equalsIgnoreCase("y"))) {
150-
// Get the credential ID from the first existing credential
151-
Map<String, Object> firstCred = existingCredentials.get(0);
152-
Object sadObj = firstCred.get("sad");
153-
154-
String existingCredId;
155-
if (sadObj instanceof Map) {
156-
existingCredId = (String) ((Map<String, Object>) sadObj).get("d");
157-
} else {
158-
existingCredId = (String) sadObj;
159-
}
160-
161-
// Retrieve the full credential
162-
Optional<String> credential = client.credentials().get(existingCredId);
163-
if (credential.isPresent()) {
164-
List<Map<String, Object>> cesrData = CESRStreamUtil.parseCESRData(credential.get());
165-
String stripped = strip(cesrData);
166-
// Build and submit transaction
167-
buildTransaction(aid.prefix(), stripped.getBytes(), VLEI_CARDANO_METADATA_SIGNER_SCHEMA_SAID, LEI);
168-
System.exit(1);
169-
} else {
170-
System.err.println("ERROR: Could not retrieve full credential data for ID: " + existingCredId);
171-
System.exit(1);
172-
}
173-
} else {
174-
System.out.println("Skipping blockchain push for existing credential.");
175-
System.exit(1);
176-
}
177-
} else {
139+
140+
if (existingCredentials.size() == 0) {
178141
System.out.println("No existing credential found.");
142+
System.exit(1);
143+
}
144+
145+
// Ask user if they want to push existing credential to chain
146+
System.out.print("\nDo you want to push the existing credential to the blockchain? (yes/no): ");
147+
String response = System.console() != null ? System.console().readLine() : new java.util.Scanner(System.in).nextLine();
148+
149+
if (response == null || (!response.equalsIgnoreCase("yes") && !response.equalsIgnoreCase("y"))) {
150+
System.out.println("Skipping blockchain push for existing credential.");
151+
System.exit(0);
152+
}
153+
154+
// Get the credential ID from the first existing credential
155+
Map<String, Object> firstCred = existingCredentials.get(0);
156+
Object sadObj = firstCred.get("sad");
157+
158+
String existingCredId;
159+
if (sadObj instanceof Map) {
160+
existingCredId = (String) ((Map<String, Object>) sadObj).get("d");
161+
} else {
162+
existingCredId = (String) sadObj;
163+
}
164+
165+
// Retrieve the full credential
166+
Optional<String> credential = client.credentials().get(existingCredId);
167+
if (credential.isPresent()) {
168+
List<Map<String, Object>> cesrData = CESRStreamUtil.parseCESRData(credential.get());
169+
String stripped = strip(cesrData);
170+
// Build and submit transaction
171+
buildTransaction(aid.prefix(), stripped.getBytes(), VLEI_CARDANO_METADATA_SIGNER_SCHEMA_SAID, LEI);
172+
} else {
173+
System.err.println("ERROR: Could not retrieve full credential data for ID: " + existingCredId);
179174
}
180175
}
181176

@@ -266,24 +261,6 @@ static void buildTransaction(String aid, byte[] credentialChain, String saidOfLe
266261
TxResult txResult = QuickTxBuilder.compose(tx)
267262
.withSigner(SignerProviders.signerFrom(account))
268263
.feePayer(account.baseAddress())
269-
.postBalanceTx((context, txn) -> {
270-
// Adjust fee AFTER balancing to account for metadata
271-
BigInteger currentFee = txn.getBody().getFee();
272-
BigInteger adjustedFee = new BigInteger("390000"); // Slightly more than required
273-
274-
// Calculate the difference to adjust the change output
275-
BigInteger feeDiff = adjustedFee.subtract(currentFee);
276-
277-
// Update fee
278-
txn.getBody().setFee(adjustedFee);
279-
280-
// Adjust the first output (change back to sender) to compensate
281-
if (!txn.getBody().getOutputs().isEmpty()) {
282-
var output = txn.getBody().getOutputs().get(0);
283-
BigInteger currentAmount = output.getValue().getCoin();
284-
output.getValue().setCoin(currentAmount.subtract(feeDiff));
285-
}
286-
})
287264
.completeAndWait();
288265
System.out.println("txResult: " + txResult);
289266
System.out.println("Transaction submitted. Tx Hash: " + txResult.getTxHash());
@@ -343,18 +320,6 @@ private static void resolveSchemas(SignifyClient client, List<String> schemaUrls
343320
}
344321
}
345322

346-
public static void getOrCreateContact(SignifyClient client, String name, String oobi) throws IOException, InterruptedException, LibsodiumException {
347-
List<Contacting.Contact> list = Arrays.asList(client.contacts().list(null, "alias", "^" + name + "$"));
348-
if (!list.isEmpty()) {
349-
Contacting.Contact contact = list.getFirst();
350-
if (contact.getOobi().equals(oobi)) {
351-
return;
352-
}
353-
}
354-
Object op = client.oobis().resolve(oobi, name);
355-
Operation<Object> waitOp = client.operations().wait(Operation.fromObject(op));
356-
}
357-
358323
private static List<Notification> waitForNotifications(String route,
359324
SignifyClient client, KeriUtils.Aid aid) throws IOException, InterruptedException {
360325
int waitTimeMs = 3000;

0 commit comments

Comments
 (0)