---
# System prepended metadata

title: zksbt service payment spec

---

# zksbt service payment spec

## Terminology

- **Service** Payment is now prior to **zksbt mint**, and bind to specific zksbt, but the dsign could be more general in this spec, so as to compatible with future demands

|params|type||
|---|---|---|
|category|bigint|zksbt mintID|
|attribute|string|zksbt attribute, such as, pomp range|
|serviceType|string|service for pay, like, **Using the value of mintId**|
|serviceData|string|a jason string of service metadata, like, <br> **{tokenId: 'tokenId'}**|



## Workflow

1. Frontend POST Request **salt** from backend
```json
    POST /npo/aigc/salt
    {
      "address": "string",
      "mintId": "string",
      "tokenId": "string"
    }
```
2. Frontend call SDK.generateServiceProof
```typescript=
    const serviceData = "{tokenId: 'tokenId'}"
    const serviceType = mintId
    const zkp = await sdk.generateServiceProof(
      category,
      attribute,
      serviceType,
      serviceData,
      salt
    )
    const nullifierHash = zkp.publicSignals.nullifierHash
    const proof = zkp.proof
```
3. Frontend POST service request.
```json
    POST /npo/aigc/servicePayment
    {
      "public_address": "string",
      "address": "string"
      "mintId": "string",
      "attribute": "string",
      "tokenId": "string",
      "serviceData": "string",
      "nullifierHash": "string",
      "proof": {}
    }
```
4. Backend Verify Proof with salt, update salt, signature service with fee.
```typescript=
    const signalHash = service_signal_hash(
      publicAddress,
      category,
      attribute,
      serviceType,
      serviceData
    )
    const valid = await verifyIdentitySignalProof(
      publicAddress,
      nullifierHash,
      signalHash,
      salt,
      this.identity_zkey,
      proof
    )
    assert(valid == true, "invalid proof")

    // fee management
    const fee = BigInt(Math.floor(Math.random() * 10000))

    const msg = service_certi_msg(
      publicAddress.toString(),
      category,
      attribute,
      serviceType,
      serviceData,
      fee
    )
    const certificate_signature = await this.signer.signMessage(msg);
    return {
      eligible : true,
      signature : certificate_signature,
      fee : fee,
    }
```
5. Frontend call SDK.payForService, metamask tx.
```typescript=
    await sdk.payForService(
      category,
      attribute,
      serviceType,
      serviceData,
      service_certificate.fee,      
      service_certificate.signature
    )
```
6. Backend Monitor On-chain Event
```solidity=
  struct ServiceInfo {
    uint publicAddress;
    uint category;
    string attribute;
    string serviceType;
    string serviceData;
  }

  event PayForService(
    ServiceInfo service,
    uint fee
  );
```



```mermaid
sequenceDiagram
    participant F	as User/Frontend
    participant B 	as Backend
    participant C 	as Contract/Blockchain

    %% Proof Key generate
    rect rgba(0, 220, 220, .3)
        F -->> B : get salt[publicAddress][service]
        B -->> F : salt[publicAddress][service]
        F -->> B : proof = zkp(service, salt)
        B -->> B : verify(service, salt)
        B -->> B : upgrade salt[publicAddress][service]
        B -->> F : signature(service, fee)
        F -->> C : payForService(service, fee, signature)
    end

```
## [DEMO](https://github.com/Manta-Network/zksbt/blob/integrate/packages/contracts/test/zksbt.test.ts#L87)


## JSSDK

@zksbt/jssdk 0.8.2

## TESTNET

0x74AAFfeB0eDd591b78BDb67Ff7cd054d4d0dA51E


