From 48602bd5c7136cb3c20cf24e172fd0955857de38 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 14 Apr 2023 12:25:32 +0930 Subject: [PATCH 01/11] Add `@verida/vda-sbt-client` dependency --- package.json | 1 + yarn.lock | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/package.json b/package.json index 913a4fd0d..d863eba48 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "@verida/client-rn": "^2.2.0", "@verida/encryption-utils": "^2.2.0", "@verida/types": "^2.2.0", + "@verida/vda-sbt-client": "^2.2.1", "@verida/verifiable-credentials": "^2.2.0", "@verida/wallet-utils": "^1.7.4", "@walletconnect/client": "^1.7.7", diff --git a/yarn.lock b/yarn.lock index 9c2341c47..4831ee2e2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4041,6 +4041,16 @@ tweetnacl "^1.0.3" tweetnacl-util "^0.15.1" +"@verida/encryption-utils@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@verida/encryption-utils/-/encryption-utils-2.2.1.tgz#76104228a194187f8019bf97e6b609d6742c67a3" + integrity sha512-0UNlTd9In2JJD8Ov5RXX9t4ta52gtpwJvg00nR4oT8TpMH7B2SEaLzJZqvBK3cRb3Y5IMJxdmjDhiParj9a+zw== + dependencies: + ethers "^5.5.1" + json.sortify "^2.2.2" + tweetnacl "^1.0.3" + tweetnacl-util "^0.15.1" + "@verida/helpers@^2.2.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@verida/helpers/-/helpers-2.2.0.tgz#1de0e0b79dbaa59ed3623535192de456e9f1308a" @@ -4051,6 +4061,16 @@ bs58 "^5.0.0" url "^0.11.0" +"@verida/helpers@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@verida/helpers/-/helpers-2.2.1.tgz#f3ea2b183e133d9f96c052b7b65da694bfed8c2f" + integrity sha512-Ozv9UTgHs3aLPOB1D7Cg/dvDl1GzAtSkGrP+eddUkZHpI5tp2b6W4McUd7sWDdERAmPAuKbeWeAZdnMXgRSlSQ== + dependencies: + "@verida/encryption-utils" "^2.2.1" + "@verida/types" "^2.2.0" + bs58 "^5.0.0" + url "^0.11.0" + "@verida/keyring@^2.2.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@verida/keyring/-/keyring-2.2.0.tgz#c7f7ace4b47ec8bceb626210b2f38d20b4f1e360" @@ -4127,6 +4147,17 @@ axios "^0.27.2" ethers "^5.7.0" +"@verida/vda-sbt-client@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@verida/vda-sbt-client/-/vda-sbt-client-2.2.1.tgz#9b5b2bda2705694f739034a5f7859593c6f396f1" + integrity sha512-SrqdM0HEnxzAybVpn9yyy0WL1ZSIvoPxwTmBOkrlPb/86/bsZIYiC1Iuae2g8XsdCu06S1I+gr/Qu8EzdyBTrw== + dependencies: + "@ethersproject/providers" "^5.7.2" + "@verida/helpers" "^2.2.1" + "@verida/web3" "^2.2.1" + axios "^0.27.2" + ethers "^5.7.0" + "@verida/verifiable-credentials@^2.2.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@verida/verifiable-credentials/-/verifiable-credentials-2.2.0.tgz#abd842f2968ca72678e17ec666d9b880905ad6ae" @@ -4167,6 +4198,14 @@ axios "^1.2.3" ethers "^5.7.0" +"@verida/web3@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@verida/web3/-/web3-2.2.1.tgz#16b338ed5b452a3269fdf2752a3d255ad7807744" + integrity sha512-5h6STyoKkZUDGVgoZt6CSOT09HzHdFV1MlshzDf4wqe2eT1hLzfyZsruSZiu20iiW/HgX4AwgBjH0o4Ga1ddrg== + dependencies: + axios "^1.2.3" + ethers "^5.7.0" + "@walletconnect/browser-utils@^1.8.0": version "1.8.0" resolved "https://registry.yarnpkg.com/@walletconnect/browser-utils/-/browser-utils-1.8.0.tgz#33c10e777aa6be86c713095b5206d63d32df0951" From cbe021aebf0bb333e7645e8d2d0be042598f881d Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 14 Apr 2023 12:32:47 +0930 Subject: [PATCH 02/11] Start of SBTManager --- src/api/SBTManager.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/api/SBTManager.ts diff --git a/src/api/SBTManager.ts b/src/api/SBTManager.ts new file mode 100644 index 000000000..0c358b392 --- /dev/null +++ b/src/api/SBTManager.ts @@ -0,0 +1,20 @@ +import { EnvironmentType, IAccount } from '@verida/types' +import { SBTClientConfig, VeridaSBTClient } from '@verida/vda-sbt-client' + +import CONFIG from '../config/environment' + +export class SBTManager { + public async init(account: IAccount): Promise { + const did = await account.did() + + const config: SBTClientConfig = { + callType: CONFIG.VERIDA_DID_CLIENT_CONFIG.callType, + did, + signKey: account.keyring, + network: CONFIG.ENVIRONMENT, + web3Options: CONFIG.VERIDA_DID_CLIENT_CONFIG.web3Config, + } + + return new VeridaSBTClient(config) + } +} From aeb9b217903c38b7f2effce0bc3a4da899414925 Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 16 Apr 2023 09:03:47 +0930 Subject: [PATCH 03/11] Remove unused vault manager files --- src/api/VaultCommon/managers/credentials.ts | 38 --------------------- src/api/VaultCommon/managers/login.ts | 25 -------------- 2 files changed, 63 deletions(-) delete mode 100644 src/api/VaultCommon/managers/credentials.ts delete mode 100644 src/api/VaultCommon/managers/login.ts diff --git a/src/api/VaultCommon/managers/credentials.ts b/src/api/VaultCommon/managers/credentials.ts deleted file mode 100644 index 15cb1bfd4..000000000 --- a/src/api/VaultCommon/managers/credentials.ts +++ /dev/null @@ -1,38 +0,0 @@ -/*import { - VeridaApp, - Database -} from "../interfaces/VeridaApp"; - -const CREDENTIAL_DB = 'credential' - -export class CredentialsManager { - - _app: VeridaApp - _db?: Database - - constructor (app: VeridaApp) { - this._app = app - } - - // @todo - async get(credentialId: string, options: object) { - await this._init() - return this._db?.get(credentialId, options) - } - - // @todo - async getMany(filter: object, options: object) { - await this._init() - return this._db?.getMany(filter, options) - } - - async _init() { - if (this._db) { - return - } - - this._db = await this._app.openDatabase(CREDENTIAL_DB) - } - -} -*/ \ No newline at end of file diff --git a/src/api/VaultCommon/managers/login.ts b/src/api/VaultCommon/managers/login.ts deleted file mode 100644 index ea6531a6e..000000000 --- a/src/api/VaultCommon/managers/login.ts +++ /dev/null @@ -1,25 +0,0 @@ - -/** - * Manage login requests and responses - */ -export class LoginManager { - - _app: any - - constructor (app: any) { - this._app = app - } - - /** - * Get a list of all login requests - */ - async getMany(filter: object, options: object) {} - - /** - * Get a specific login request - * - * @param requestId - */ - async get(requestId: string) {} - -} \ No newline at end of file From ded2a10adee6ccc7868a7dfe1a49ecb54d0cdaf3 Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 16 Apr 2023 11:47:51 +0930 Subject: [PATCH 04/11] Pull connectors from the server. Trigger SBT credential saving if included in the profile. --- src/api/DataConnectorsManager.ts | 75 ++++++++++++++++---------- src/pages/Connections/DataConnector.js | 2 +- 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/src/api/DataConnectorsManager.ts b/src/api/DataConnectorsManager.ts index 70a301b92..1a4c8d1e5 100644 --- a/src/api/DataConnectorsManager.ts +++ b/src/api/DataConnectorsManager.ts @@ -6,6 +6,7 @@ import { Linking } from 'react-native' import CONFIG from '../config/environment' import AccountManager from './AccountManager' +import { SBTManager } from './SBTManager' const DATA_CONNECTION_SCHEMA = 'https://vault.schemas.verida.io/data-connections/connection/v0.1.0/schema.json' @@ -20,24 +21,9 @@ const delay = async (ms: number) => { await new Promise((resolve: any) => setTimeout(() => resolve(), ms)) } -// possible states for status: syncing, disabled, active +let CONNECTION_CACHE: any -// @todo: Pull this from the server -const FacebookIcon = require('assets/social_icons/facebook.png') -const TwitterIcon = require('assets/social_icons/twitter.png') - -const CONNECTIONS: any = { - facebook: { - name: 'facebook', - label: 'Facebook', - icon: FacebookIcon, - }, - twitter: { - name: 'twitter', - label: 'Twitter', - icon: TwitterIcon, - }, -} +// possible states for status: syncing, disabled, active class DataConnectorsEvents extends EventEmitter { private static instance: DataConnectorsEvents @@ -85,7 +71,19 @@ export default class DataConnectorsManager { return DataConnectorsManager.datastore } - static getConnectionInfo(connectorName: string) { + static async getConnections(): Promise> { + if (CONNECTION_CACHE) { + return CONNECTION_CACHE + } + + // @todo cache + const response = await axios.get(`${CONFIG.DATA_CONNECTOR_URL}/providers`) + CONNECTION_CACHE = response.data + return CONNECTION_CACHE + } + + static async getConnectionInfo(connectorName: string) { + const CONNECTIONS = await DataConnectorsManager.getConnections() return CONNECTIONS[connectorName] } @@ -94,7 +92,15 @@ export default class DataConnectorsManager { return DataConnectorsManager._connections[connectorName] } - const connector = new DataConnection(connectorName) + const connectionInfo = await DataConnectorsManager.getConnectionInfo( + connectorName + ) + + const connector = new DataConnection( + connectorName, + connectionInfo.icon, + connectionInfo.label + ) await connector.init() DataConnectorsManager._connections[connectorName] = connector @@ -102,7 +108,9 @@ export default class DataConnectorsManager { } static async getConnectors(): Promise { - const connections: any = Object.values(CONNECTIONS) + const connections: any = Object.values( + await DataConnectorsManager.getConnections() + ) const connectors: any = {} for (let i = 0; i < connections.length; i++) { const connection = await DataConnectorsManager.getConnection( @@ -115,7 +123,9 @@ export default class DataConnectorsManager { } static async resetConnector() { - const connections: any = Object.values(CONNECTIONS) + const connections: any = Object.values( + await DataConnectorsManager.getConnections() + ) for (let i = 0; i < connections.length; i++) { if ( DataConnectorsManager._connections[connections[i].name].syncStatus !== @@ -174,12 +184,12 @@ class DataConnection extends EventEmitter { public metadata?: any public icon?: any - constructor(name: string) { + constructor(name: string, icon: string, label: string) { super() this.name = this.source = name this.syncStatus = 'disabled' - this.icon = CONNECTIONS[this.name].icon - this.label = CONNECTIONS[this.name].label + this.icon = icon + this.label = label this.syncFrequency = 'hour' } @@ -369,9 +379,20 @@ class DataConnection extends EventEmitter { const syncRequest = await externalDatastore.get(syncRequestId) if (syncRequest.status === 'complete') { - // Sync has completed on the server, so complete the sync - // by replicating data from the server - this.syncReplication(serverDid, contextName, syncRequest) + // Sync has completed on the server + + // Save a SBT credential if it was provided + if (syncRequest.syncInfo.profile.credential) { + const sbtManager = new SBTManager() + const profileCredentialId = `${syncRequest.source}-${syncRequest.syncInfo.profile.id}-profile` + await sbtManager.saveCredential( + profileCredentialId, + syncRequest.syncInfo.profile.credential + ) + } + + // Complete the sync by replicating data from the server + await this.syncReplication(serverDid, contextName, syncRequest) } else { if (retryCount === 0) { // Retry count limit hit diff --git a/src/pages/Connections/DataConnector.js b/src/pages/Connections/DataConnector.js index db472bed1..19e7f8a9b 100644 --- a/src/pages/Connections/DataConnector.js +++ b/src/pages/Connections/DataConnector.js @@ -69,7 +69,7 @@ export default (props) => { }} style={styles.connectionItem}> - + {item.label} {item.syncStatus} From 2b4eb7bd8adf2dec3e5ee500164b171c6a38eab1 Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 16 Apr 2023 11:48:36 +0930 Subject: [PATCH 05/11] Basic SBT Manager working. Issues with SBT client library in the protocol though. --- src/api/SBTManager.ts | 332 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 321 insertions(+), 11 deletions(-) diff --git a/src/api/SBTManager.ts b/src/api/SBTManager.ts index 0c358b392..0d378c51c 100644 --- a/src/api/SBTManager.ts +++ b/src/api/SBTManager.ts @@ -1,20 +1,330 @@ -import { EnvironmentType, IAccount } from '@verida/types' -import { SBTClientConfig, VeridaSBTClient } from '@verida/vda-sbt-client' +import EncryptionUtils from '@verida/encryption-utils' +import { + buildVeridaUri, + explodeDID, + explodeVeridaUri, + wrapUri, +} from '@verida/helpers' +import { + DatabasePermissionOptionsEnum, + EnvironmentType, + IContext, + IDatastore, + Web3CallType, +} from '@verida/types' +import { VeridaSBTClient } from '@verida/vda-sbt-client' +import { Credentials } from '@verida/verifiable-credentials' +import _ from 'lodash' import CONFIG from '../config/environment' +import AccountManager from './AccountManager' +import { Account } from './types' + +const SCHEMA_SBT = + 'https://common.schemas.verida.io/token/sbt/storage/v0.1.0/schema.json' +const SCHEMA_CREDENTIALS = + 'https://common.schemas.verida.io/credential/base/v0.2.0/schema.json' export class SBTManager { - public async init(account: IAccount): Promise { - const did = await account.did() + private client?: VeridaSBTClient - const config: SBTClientConfig = { - callType: CONFIG.VERIDA_DID_CLIENT_CONFIG.callType, - did, - signKey: account.keyring, - network: CONFIG.ENVIRONMENT, - web3Options: CONFIG.VERIDA_DID_CLIENT_CONFIG.web3Config, + /** + * Save a SBT credential + * + * @param id + * @param credential + * @param forceUpdate + */ + public async saveCredential(id: string, credential: any) { + console.log('saveCredential()') + const context = ( + await AccountManager.getInstance().getVeridaContext() + ) + + // Open the datastore + const datastore = await context.openDatastore(SCHEMA_CREDENTIALS, {}) + const credentialRecord = { + _id: id, + ...credential, + } + + // Try to fetch an existing record + let existingRecord + try { + existingRecord = await datastore.get(id, {}) + + // Record exists, + const { _rev } = existingRecord + + if ( + !_.isEqual( + existingRecord.credentialData, + credentialRecord.credentialData + ) + ) { + // Data has changed, need to update + // Set the existing record revision so update process correctly + credentialRecord._rev = _rev + + // Data that changed + //const changes = _.differenceWith(_.toPairs(existingRecord.credentialData), _.toPairs(credentialRecord.credentialData), _.isEqual) + //console.log(changes) + + // Save the credential record + if (!(await datastore.save(credentialRecord, {}))) { + console.log('Invalid SBT credential', datastore.errors) + } + } + } catch (err) { + // Record doesn't exist, create it + await datastore.save(credentialRecord, { + forceInsert: true, + }) + } + } + + public async burnSbt( + credentialRecord: any, + mintAddress: string + ): Promise { + mintAddress = mintAddress.toLowerCase() + const context = ( + await AccountManager.getInstance().getVeridaContext() + ) + + // Open the datastore + const datastore = await context.openDatastore(SCHEMA_SBT, { + permissions: { + read: DatabasePermissionOptionsEnum.PUBLIC, + write: DatabasePermissionOptionsEnum.OWNER, + }, + }) + + // Get the minted SBT + const sbtId = `${mintAddress}-${credentialRecord._id}` + let sbtRecord + try { + sbtRecord = await datastore.get(sbtId, {}) + } catch (err) { + // doesn't exist + throw new Error(`SBT hasn't been minted`) } - return new VeridaSBTClient(config) + // Delete the minted SBT from the public database + //await datastore.delete(sbtId) + + // Unmint the SBT + const client = await this.getClient() + + /*try { + const claimedSbts = await client.getClaimedSBTList(mintAddress.toLowerCase()) + console.log(claimedSbts) + } catch (err) { + console.log(err.message) + }*/ + try { + const response = await client.burnSBT(59) + console.log('burnt', response) + } catch (err) { + console.log('burn error') + console.log(err.message) + return false + } + } + + /** + * Mint a SBT + * + * @param credentialRecord + * @param mintAddress + */ + public async mintSbt( + credentialRecord: any, + mintAddress: string + ): Promise { + mintAddress = mintAddress.toLowerCase() + // @todo: check it hasn't been minted already + console.log(credentialRecord, mintAddress) + //return + + const context = ( + await AccountManager.getInstance().getVeridaContext() + ) + + // Open the datastore + const datastore = await context.openDatastore(SCHEMA_SBT, { + permissions: { + read: DatabasePermissionOptionsEnum.PUBLIC, + write: DatabasePermissionOptionsEnum.OWNER, + }, + }) + + // Check this SBT hasn't already been minted + const sbtId = `${mintAddress}-${credentialRecord._id}` + try { + await datastore.get(sbtId, {}) + console.log('already exists', sbtId) + // exists + return false + } catch (err) { + // doesn't exist + } + + // Save this SBT + const sbtData: any = { + _id: sbtId, + ...credentialRecord.credentialData, + didJwtVc: credentialRecord.didJwtVc, + } + + console.log('sbtData', sbtData) + + const result: any = await datastore.save(sbtData, { + forceInsert: true, + }) + console.log(result) + console.log(datastore.errors) + const db = await datastore.getDb() + const info = await db.info() + const credentialUri = buildVeridaUri( + await context.getAccount().did(), + context.getContextName(), + info.databaseName, + sbtId, + [] + ) + console.log(credentialUri) + + //const credentialUri = 'verida://did:vda:testnet:0xcD61d79C7db8fF5F80feCacEc0aE57274F5D6dF5/Verida%20Testing:%20Fake%20Vault/token_metadata_public/5d99c6e0-d38a-11ed-8135-f5f9ab7f39c3' + + // Fetch credential record from the network + /*const credentialRecord = await fetchVeridaUri( + credentialUri, + context.getClient() + )*/ + + // Generate URL to mint that generates the metadata + const sbtUri = wrapUri(credentialUri, 'https://data.verida.network') + console.log('sbtUri', sbtUri) + + const credentials = new Credentials() + + //const sbtClient = await SbtController.getSbtClient() + const generatedCredential = await credentials.verifyCredential( + credentialRecord.didJwtVc, + {} + ) + //const sbtData = generatedCredential.verifiableCredential.credentialSubject + const proofs = generatedCredential.payload.vc.proofs + const vcIssuerDid = generatedCredential.payload.iss + + // Get the context proof of the issuer + // (Links their DID to the signing key of the context that signed the credential proof) + // @ts-ignore + const didClient = context.getClient().didClient + const issuerDidDoc = await didClient.get(vcIssuerDid) + const issuerContextProof = issuerDidDoc.locateContextProof( + generatedCredential.payload.vc.veridaContextName + ) + + console.log('issuerDid', vcIssuerDid) + console.log('issuerContextProof', issuerContextProof) + const { did } = explodeVeridaUri(credentialUri) + console.log('subject did', did) + const { address } = explodeDID(did) + const proofString = `${sbtData.type}-${ + sbtData.uniqueAttribute + }-${address.toLowerCase()}` + console.log('proof string', proofString) + console.log(proofs['type-unique-didAddress']) + + const signingAddress = EncryptionUtils.getSigner( + proofString, + proofs['type-unique-didAddress'] + ) + console.log('address that signed SBT string (issuer)', signingAddress) + + /* + const issuerDidAddress = '0xB3d245bC0Fa8479b1B0b200c26f8c93e4737efC3' + const requestProofMsg = `${issuerDidAddress}${signingAddress}`.toLowerCase() + const privateKeyArray = new Uint8Array( + Buffer.from(serverconfig.testing.veridaPrivateKey.slice(2), 'hex') + )*/ + //const testSign = EncryptionUtils.signData(requestProofMsg, privateKeyArray) + /*const signerContextSigner = EncryptionUtils.getSigner( + requestProofMsg, + issuerContextProof + ) + console.log( + 'requestProofMsg (issuer signing context text)', + requestProofMsg + ) + console.log( + 'signerContextSigner (issuer signing context proof)', + signerContextSigner + )*/ + /*console.log('test sign', testSign) + + console.log('these two should match') + console.log(testSign, issuerContextProof) + + const keyring = await connection.account.keyring(generatedCredential.payload.vc.veridaContextName) + + // Get keyring keys so public keys and ownership proof can be saved to the DID document + const keys = await keyring.getKeys() + console.log(keys) + + // Generate a proof that the DID controls the context public signing key that can be used on chain + const proofStringReal = `${issuerDidAddress}${keys.signPublicAddress}`.toLowerCase() + console.log('real proof string', proofStringReal) + + const signer2 = EncryptionUtils.getSigner(proofStringReal, issuerContextProof) + console.log('signer2', signer2)*/ + + //return + + // Initiate a SBT claim on-chain + + try { + const client = await this.getClient() + const mintResult = await client.claimSBT( + sbtData.type, + sbtData.uniqueAttribute, + sbtUri, + mintAddress, + proofs['type-unique-didAddress'], + issuerContextProof + ) + + console.log('mint result') + console.log(mintResult) + return true + } catch (err) { + console.log('mint error!') + console.log(err.message) + console.log(err.reason) + } + } + + private async getClient() { + if (this.client) { + return this.client + } + + const didClientConfig = CONFIG.VERIDA_DID_CLIENT_CONFIG + const account = ( + await AccountManager.getInstance().getSelectedAccount() + ) + + const sbtClient = new VeridaSBTClient({ + callType: didClientConfig.callType, + did: account.did, + signKey: account.privateKey, + network: CONFIG.ENVIRONMENT, + web3Options: didClientConfig.web3Config, + }) + + this.client = sbtClient + return this.client } } From 01aaef7866673f9b3826700a6602471c0ec9ad67 Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 16 Apr 2023 11:48:53 +0930 Subject: [PATCH 06/11] Add basic mint / burn buttons on credentials for testing. --- src/pages/Data/CredentialDataItem.tsx | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/pages/Data/CredentialDataItem.tsx b/src/pages/Data/CredentialDataItem.tsx index 365471f1f..ebc061de6 100644 --- a/src/pages/Data/CredentialDataItem.tsx +++ b/src/pages/Data/CredentialDataItem.tsx @@ -20,7 +20,9 @@ import { QRCode } from 'react-native-custom-qr-codes-expo' import AntDesign from 'react-native-vector-icons/AntDesign' import AccountManager from 'api/AccountManager' +import { SBTManager } from 'api/SBTManager' import { DefaultAvatar } from 'api/utils' +import Button from 'components/Button' import DataFieldList from 'components/Data/DataFieldList' import LoadingView from 'components/LoadingView' import Text from 'components/Text' @@ -100,6 +102,18 @@ function CredentialDataItem(props: CredentialDataItemProps) { ) } + async function mintSbt() { + const sbtManager = new SBTManager() + const mintAddress = '0x239F6455b8113C7c6b2275bA32720667E5CeE074' + await sbtManager.mintSbt(item, mintAddress) + } + + async function burnSbt() { + const sbtManager = new SBTManager() + const mintAddress = '0x239F6455b8113C7c6b2275bA32720667E5CeE074' + await sbtManager.burnSbt(item, mintAddress) + } + function toggleFullscreenQr() { setShowFullscreenQr((prevState) => !prevState) } @@ -121,6 +135,14 @@ function CredentialDataItem(props: CredentialDataItemProps) { )} + + + + {!loading && verified && ( From b3f9538257777f16072d78d7a491ba9f55de3ce7 Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 17 Apr 2023 08:09:48 +0930 Subject: [PATCH 07/11] Fix connection display with updated provider details --- src/pages/Connections/DataConnector.js | 2 +- src/pages/Connections/SingleConnection.js | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/pages/Connections/DataConnector.js b/src/pages/Connections/DataConnector.js index 19e7f8a9b..91e5e1b21 100644 --- a/src/pages/Connections/DataConnector.js +++ b/src/pages/Connections/DataConnector.js @@ -64,7 +64,7 @@ export default (props) => { { props.navigation.navigate('SingleConnection', { - provider: item.name, + provider: item, }) }} style={styles.connectionItem}> diff --git a/src/pages/Connections/SingleConnection.js b/src/pages/Connections/SingleConnection.js index 7ba549373..1fc6680c0 100644 --- a/src/pages/Connections/SingleConnection.js +++ b/src/pages/Connections/SingleConnection.js @@ -22,8 +22,8 @@ const calculateNextSync = function (conn) { } export default ({ route, navigation }) => { - const provider = route.params.provider - const connectionInfo = DataConnectorsManager.getConnectionInfo(provider) + const connectionInfo = route.params.provider + const provider = connectionInfo.name const [syncStatus, setSyncStatus] = useState('') const [nextSync, setNextSync] = useState('') @@ -105,7 +105,10 @@ export default ({ route, navigation }) => { )} - + {syncStatus === 'disabled' ? ( From b7730680175e0fac509df659be94498d106e8ac8 Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 17 Apr 2023 08:48:32 +0930 Subject: [PATCH 10/11] Load collectibles for polygon, not ethereum --- src/pages/Assets/Collectibles.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/Assets/Collectibles.tsx b/src/pages/Assets/Collectibles.tsx index e6bd25328..c6cf89bbc 100644 --- a/src/pages/Assets/Collectibles.tsx +++ b/src/pages/Assets/Collectibles.tsx @@ -39,8 +39,9 @@ import { Theme } from 'styles/types' import { IMAGE_WIDTH, NUMBER_OF_COLUMNS } from './constants' const caipNormalizeAddress = (address: string) => { - // FIXME: hardcode just ethereum for now - return `eip155:5:${address}` + // FIXME: hardcode just mumbai for now + // was 5 + return `eip155:80001:${address}` } const Collectibles = () => { From 30b77e20e714467f6c35d15ee63d2a361504ec86 Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 17 Apr 2023 11:00:47 +0930 Subject: [PATCH 11/11] Force `.json` extension on minted SBTs. Update `isMinted()` to reference the `did` --- src/api/SBTManager.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/api/SBTManager.ts b/src/api/SBTManager.ts index 4b74d91cd..7c778e9db 100644 --- a/src/api/SBTManager.ts +++ b/src/api/SBTManager.ts @@ -83,13 +83,14 @@ export class SBTManager { } } - public async isMinted(credentialRecord: any, mintAddress: string) { - console.log('isMinted?', mintAddress) + public async isMinted(credentialRecord: any) { + console.log('isMinted?', credentialRecord) const client = await this.getClient() + console.log(credentialRecord.credentialData.did.toLowerCase()) try { const claimedSbts = await client.getClaimedSBTList( - mintAddress.toLowerCase() + credentialRecord.credentialData.did.toLowerCase() ) console.log(claimedSbts) } catch (err) { @@ -220,7 +221,7 @@ export class SBTManager { )*/ // Generate URL to mint that generates the metadata - const sbtUri = wrapUri(credentialUri, 'https://data.verida.network') + const sbtUri = wrapUri(credentialUri, 'https://data.verida.network') + '.json' console.log('sbtUri', sbtUri) const credentials = new Credentials()