All VCs has following basic schema (TODO: write formal schema):
{
_context: ["https://www.w3.org/ns/credentials/v2"],
id: "did:ethr:0xbaad",
_type: ["VerifiableCredential", "MyCred"],
issuer: {
id: "did:ethr:0xdeadbeaf"
},
credentialSubject: {
id: "did:ethr:0xc00ffebabe"
}
}
Where:
_context
is equivalent to standard@_context
id
is a DID of the VC itself_type
is equivalent to standardtype
issuer
is a DID of the VC issuercredentialSubject
describes the subject and contains:id
is a DID of the VC subject- any number of specific claims (depends on
_type
)
Although we present VCs as JSON in this document, they're actually EIP-712 TypedStructs.
This type contains claim that given subject can control issuer's Smart Account. In our case, issuer is always equal to the subject.
{
_context: ["https://www.w3.org/ns/credentials/v2"],
id: "did:ethr:0xbaad",
_type: ["VerifiableCredential", "InBlancoAccountController"],
issuer: {
id: "did:ethr:0xdeadbeaf"
},
credentialSubject: {
id: "did:ethr:0xdeadbeaf"
}
}
This type contains claim that given subject (a Smart Account) can pay for a single transaction using funds deposited by issuer in the paymaster.
{
_context: ["https://www.w3.org/ns/credentials/v2"],
id: "did:ethr:0xbaad",
_type: ["VerifiableCredential", "TransactionPaid"],
issuer: {
id: "did:ethr:0xc0febabe"
},
credentialSubject: {
id: "did:ethr:0xdeadbeaf"
}
}
This type contains claim that given subject (Bob's new wallet) registered as the new controller of a Smart Account. Issued by our backend based on InBlancoAccountController
.
{
_context: ["https://www.w3.org/ns/credentials/v2"],
id: "did:ethr:0xbaad",
_type: ["VerifiableCredential", "RegisteredAccountController"],
issuer: {
id: "did:ethr:0xbaadb10c"
},
credentialSubject: {
id: "did:ethr:0x00ff00ff",
registeredWith: {
id: "did:ethr:0xbaad"
}
}
}
Actors:
- Alice - person that wants to send assets
- Bob - person that will receive assets
- Backend - service that issues
RegisteredAccountController
VCs to prevent front-running / replay attacks
- Alice generates a DID for Smart Account.
- Alice creates Smart Account on chain.
- Alice creates an
InBlancoAccountController
VC:- Issuer - Smart Account DID
- Subject - Smart Account DID
- Alice deposits ETH in Paymaster.
- Alice creates an
TransactionPaid
VC:- Issuer - Alice
did:ethr:
DID - Subject - Smart Account DID
- Issuer - Alice
- Alice sends both VCs over to Bob
- Bob takes
InBlancoAccountController
VC and shows it + his new wallet address to the Backend - Backend verifies the VC and that it was never used before and it issues
RegisteredAccountController
VC and gives it to Bob:- Issuer - Backend DID
- Subject - Bob's wallet
- Bob sends all VCs + his transaction to the chain
- Smart Account verifies that:
- Tx is signed somehow with EOA
InBlancoAccountController
:- issuer matches subject matches the Smart Account
- signature is valid
RegisteredAccountController
:- issuer matches configured backend DID
- subject matches the Tx signer
- signature is valid
- registeredWith matches the
InBlancoAccountController
- Paymaster verifies that:
TransactionPaid
:- Issuer - can be anyone, but needs enough balance in paymaster to cover the fee
- Subject - matches the Smart Account
- signature is valid
- DID of this VC wasn't used before