Mind Lake SDK
  • Overview
  • Get started
    • Tutorial step-by-step
    • TypeScript Quick-Start
    • Python Quick-Start
  • Use Cases
    • 1-Single User with Structured Data
    • 2-Single User with UnStructured Data
    • 3-Multi Users with Permission Sharing
  • Glossary
  • TYPESCRIPT API REFERENCE
    • MindLake
    • MindLake.DataLake
    • MindLake.Cryptor
    • MindLake.Permission
    • Return Code
  • PYTHON API REFERENCE
    • MindLake
    • MindLake.DataLake
    • MindLake.Cryptor
    • MindLake.Permission
    • Return Code
Powered by GitBook
On this page
  • 3.1. Task
  • 3.2. Data
  • Alice
  • Bob
  • 3.3. Example code to Insert cipher and grant permission
  • 3.4. Result Table in MindLake
  • Alice
  • Bob
  • 3.5. Example code to confirm permission and calculate on cipher
  • 3.6. Output
  1. Use Cases

3-Multi Users with Permission Sharing

Previous2-Single User with UnStructured DataNextGlossary

Last updated 1 year ago

In this scenario, Alice and Bob are traders who possess sensitive transaction volume information for various wallets. They need to securely store this data and share it with Charlie, who is responsible for providing settlement services. To ensure data privacy and security, Alice and Bob choose to encrypt the transaction data before storing it in their respective tables.

This use case will use multiple wallet address. During testing period, please make you have all wallet address are registered in into .

Be more specific, please ensure your Alice, Bob and Charlie are registered and approved.

3.1. Task

  1. Alice and Bob are two traders who possess transaction volume information for several wallets. They will encrypt this data and insert it into their respective tables.

  2. Charlie is responsible for providing settlement services. To facilitate this, Alice and Bob grant Charlie permission to access their tables.

  3. Charlie then executes a query, aggregates the data, and calculates the total volume for each wallet.

3.2. Data

Alice

Wallet Address(text)
Token (text)
Volume (float4)

(secret data)

(secret data)

(secret data)

0x8CFB38b2cba74757431B205612E349B8b9a9E661

USDT

5.6

0xD862D48f36ce6298eFD00474eC852b8838a54F66

BUSD

6.3

0x8CFB38b2cba74757431B205612E349B8b9a9E661

BUSD

10.3

Bob

Wallet Address(text)
Token (text)
Volume (float4)

(secret data)

(secret data)

(secret data)

0xD862D48f36ce6298eFD00474eC852b8838a54F66

USDT

3.3

0x70dBcC09edF6D9AdD4A235e2D8346E78A79ac770

BUSD

9.8

0x70dBcC09edF6D9AdD4A235e2D8346E78A79ac770

USDT

7.7

3.3. Example code to Insert cipher and grant permission

// ATTENTION: 
// This use case will use multiple wallet address. 
// During testing period, please make you have all wallet address are registered in into whitelist: https://sites.google.com/mindnetwork.xyz/mindnetwork/alpha-test
// Be more specific, please ensure your Alice, Bob and Charlie are registered and approved. 

import {MindLake} from 'mind-lake-sdk';

const DataType = MindLake.DataType;

const dataAlice = [
  { WalletAddress: "0x8CFB38b2cba74757431B205612E349B8b9a9E661", Token: 'USDT', Volume: "5.6" },
  { WalletAddress: "0xD862D48f36ce6298eFD00474eC852b8838a54F66", Token: 'BUSD', Volume: "6.3" },
  { WalletAddress: "0x8CFB38b2cba74757431B205612E349B8b9a9E661", Token: 'BUSD', Volume: "10.3" },
];

const dataBob = [
  {'wallet': '0xD862D48f36ce6298eFD00474eC852b8838a54F66', 'token': 'USDT', 'volume': 3.3},
  {'wallet': '0x70dBcC09edF6D9AdD4A235e2D8346E78A79ac770', 'token': 'BUSD', 'volume': 9.8},
  {'wallet': '0x70dBcC09edF6D9AdD4A235e2D8346E78A79ac770', 'token': 'USDT', 'volume': 7.7}
];

const insertData = async (data: Array<any>) => {
const mindLake = await MindLake.getInstance("YOU OWN APP KEY");

// connect to MindLake."5" is example of Goerli Testnet chainId
const chainId = "5"
const res1 = await mindLake.connect(chainId);
if(res1.code !== 0) {
  console.error(res1.message);
  return
}

// create a table
const dataLake = mindLake.dataLake;
await dataLake.dropTable("transaction");
const res2 = await dataLake.createTable("transaction", [{columnName: 'WalletAddress', type: DataType.text, encrypt: false}, {columnName: 'Token', type: DataType.text, encrypt: true}, {columnName: 'Volume', type: DataType.float4, encrypt: true}],);
if(res2.code !==0) {
  console.error(res2.message);
  return
}

// encrypt data
const cryptor = mindLake.cryptor;
for (const row of data) {
  const walletAddress = row.WalletAddress;
  const encryptToken = await cryptor.encrypt(row.Token, "transaction.Token");
  const encryptVolume = await cryptor.encrypt(row.Volume, "transaction.Volume");
  const sql = `insert into transaction ("WalletAddress", "Token", "Volume") values ('${walletAddress}', '${encryptToken.result}', '${encryptVolume.result}')`;
  const sqlRes = await dataLake.query(sql);
  if(sqlRes.code !== 0) {
    return console.error(sqlRes.message)
  }
}
const permission = mindLake.permission;
const result = await permission.grant(chainId,"charlieWalletAddress", ['transaction.Token', 'transaction.Volume'])
if(result.code !==0 ) {
  console.error(result.message);
  return
}
};

const excute = async () => {
  await insertData(dataAlice);
  await insertData(dataBob);
}
import env
import mindlakesdk
import logging

# the policy grant target should be an existing user in MindLake, so first register Charlie
# '5' is example of Goerli Testnet chainID
chainID = '5'
mindlake = mindlakesdk.connect(env.walletPrivateKeyCharlie, env.appKey, chainID)
assert mindlake, mindlake.message

def writeDataGrantToCharlie(walletPrivateKey, appKey, data) -> str:
    # connect to MindLake
    mindlake = mindlakesdk.connect(walletPrivateKey, appKey, chainID)
    assert mindlake, mindlake.message

    # create a table
    result = mindlake.datalake.createTable('transaction_temp',
            [
                mindlake.datalake.Column('WalletAddress', mindlake.DataType.text, True),
                mindlake.datalake.Column('Token', mindlake.DataType.text, True),
                mindlake.datalake.Column('Volume', mindlake.DataType.float4, True)
            ])
    assert result, result.message

    # encrypt and insert
    for row in data:
        result = mindlake.datalake.query(f"""
        INSERT INTO "transaction_temp" ("WalletAddress", "Token", "Volume")
        VALUES (
            '{mindlake.cryptor.encrypt(row["wallet"],'transaction_temp.WalletAddress').data}',
            '{mindlake.cryptor.encrypt(row["token"],'transaction_temp.Token').data}',
            '{mindlake.cryptor.encrypt(row["volume"],'transaction_temp.Volume').data}')
        """)
        assert result, result.message

    result = mindlake.permission.grant(env.walletAddressCharlie,
        ['transaction_temp.WalletAddress', 'transaction_temp.Token', 'transaction_temp.Volume'])
    assert result, result.message
    policyID = result.data
    return policyID

# Alice write data to table and grant permission to Charlie    
policyIDAlice = writeDataGrantToCharlie(env.walletPrivateKeyAlice, env.appKey, [
    {'wallet': '0x8CFB38b2cba74757431B205612E349B8b9a9E661', 'token': 'USDT', 'volume': 5.6},
    {'wallet': '0xD862D48f36ce6298eFD00474eC852b8838a54F66', 'token': 'BUSD', 'volume': 6.3},
    {'wallet': '0x8CFB38b2cba74757431B205612E349B8b9a9E661', 'token': 'BUSD', 'volume': 10.3}
])

# Bob write data to table and grant permission to Charlie
policyIDBob = writeDataGrantToCharlie(env.walletPrivateKeyBob, env.appKey, [
    {'wallet': '0xD862D48f36ce6298eFD00474eC852b8838a54F66', 'token': 'USDT', 'volume': 3.3},
    {'wallet': '0x70dBcC09edF6D9AdD4A235e2D8346E78A79ac770', 'token': 'BUSD', 'volume': 9.8},
    {'wallet': '0x70dBcC09edF6D9AdD4A235e2D8346E78A79ac770', 'token': 'USDT', 'volume': 7.7}
])

3.4. Result Table in MindLake

Alice

Wallet Address
Token
Volume

(text, encrypt=False)

(text, encrypt=True)

(float4, encrypt=True)

0x8CFB38b2cba74757431B205612E349B8b9a9E661

0x1111

0x2211

0xD862D48f36ce6298eFD00474eC852b8838a54F66

0x1122

0x2222

0x8CFB38b2cba74757431B205612E349B8b9a9E661

0x1133

0x2233

Bob

Wallet Address
Token
Volume

(text, encrypt=False)

(text, encrypt=True)

(float4, encrypt=True)

0xD862D48f36ce6298eFD00474eC852b8838a54F66

0x1144

0x2244

0x70dBcC09edF6D9AdD4A235e2D8346E78A79ac770

0x1155

0x2255

0x70dBcC09edF6D9AdD4A235e2D8346E78A79ac770

0x1166

0x2266

3.5. Example code to confirm permission and calculate on cipher

const mindLake = await MindLake.getInstance("YOU OWN APP KEY");
// Charlie connect to MindLake. "5" is example of Goerli Testnet chainId
const chainId = "5"
let res = await mindLake.connect(chainId);
if(res.code !== 0) {
  return console.error(res.message);
}
const permission =  mindLake.permission;
const dataLake =  mindLake.dataLake;
const cryptor = mindLake.cryptor;
res = await permission.confirm("policyAliceID");
if(res.code !== 0) {
  return console.error(res.message);
}
res = await permission.confirm("policyBobID");
if(res.code !== 0) {
  return console.error(res.message);
}
const sql = `SELECT combine."WalletAddress", SUM(combine."Volume") FROM(SELECT "WalletAddress","Volume" FROM "${aliceWalletAddress.toLocaleLowerCase()}"."transaction"UNION ALLSELECT "WalletAddress","Volume" FROM "${bobWalletAddress.toLocaleLowerCase()}"."transaction") as combineGROUP BY "WalletAddress"`;
res = await dataLake.query(sql);
if(res.code !== 0) {
  return console.error(res.message);
}
for (const row of res.result.data) {
  const walletAddress = row[0];
  res = await cryptor.decrypt(row[1]);
  if(res.code !== 0) {
    return console.error(res.message);
  }
  console.log(`${walletAddress} >>> `, res.result)
}
# Charlie confirm the permission
# '5' is example of Goerli Testnet chainID
chainID = '5'
mindlake = mindlakesdk.connect(env.walletPrivateKeyCharlie, env.appKey, chainID)
assert mindlake, mindlake.message
result = mindlake.permission.confirm(policyIDAlice)
assert result, result.message
result = mindlake.permission.confirm(policyIDBob)
assert result, result.message

# Charlie query and calculate the total volume of each wallet
result = mindlake.datalake.query(f'''
SELECT combine."WalletAddress", SUM(combine."Volume") FROM
(SELECT "WalletAddress","Volume" FROM "{env.walletAddressAlice[2:].lower()}"."transaction_temp"
UNION ALL
SELECT "WalletAddress","Volume" FROM "{env.walletAddressBob[2:].lower()}"."transaction_temp") as combine
GROUP BY "WalletAddress"
''')
assert result, result.message

print('-'*57)
print('|', result.data["columnList"][0], " "*28, '|', result.data["columnList"][1], '\t|')
print('-'*57)
for row in result.data['data']:
    result = mindlake.cryptor.decrypt(row[0])
    assert result, result.message
    walletAddress = result.data
    result = mindlake.cryptor.decrypt(row[1])
    assert result, result.message
    sumVolume = result.data
    print(f'| {walletAddress} | {sumVolume:.1f}\t|')
print('-'*57)

3.6. Output

---------------------------------------------------------
| WalletAddress                              | sum      |
---------------------------------------------------------
| 0xD862D48f36ce6298eFD00474eC852b8838a54F66 | 9.6      |
| 0x70dBcC09edF6D9AdD4A235e2D8346E78A79ac770 | 17.5     |
| 0x8CFB38b2cba74757431B205612E349B8b9a9E661 | 15.9     |
---------------------------------------------------------
whitelist