-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclient-example.js
More file actions
110 lines (92 loc) · 3.43 KB
/
Copy pathclient-example.js
File metadata and controls
110 lines (92 loc) · 3.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// client-example.js
// Example client implementation for Soulbound Auth
class SoulboundAuthClient {
constructor(config) {
this.serverUrl = config.serverUrl;
this.sbtContract = config.sbtContract;
this.provider = null;
this.signer = null;
this.token = null;
}
async connect() {
// Connect wallet
await window.ethereum.request({ method: 'eth_requestAccounts' });
this.provider = new ethers.providers.Web3Provider(window.ethereum);
this.signer = this.provider.getSigner();
const address = await this.signer.getAddress();
// Sign authentication message
const message = `Authenticate\nTimestamp: ${Date.now()}`;
const signature = await this.signer.signMessage(message);
// Send to server
const response = await fetch(`${this.serverUrl}/auth`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ address, signature, message })
});
const data = await response.json();
this.token = data.token;
return {
hasSBT: data.hasSBT,
accountId: data.accountId
};
}
async mintSBT(eulaHash, version) {
// Call contract to mint
const sbt = new ethers.Contract(this.sbtContract, SBT_ABI, this.signer);
const tx = await sbt.mintSBT(eulaHash, version);
const receipt = await tx.wait();
// Confirm with server
const address = await this.signer.getAddress();
const message = `Confirm SBT mint: ${receipt.transactionHash}`;
const signature = await this.signer.signMessage(message);
const response = await fetch(`${this.serverUrl}/confirm-mint`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.token}`
},
body: JSON.stringify({
address,
signature,
eulaHash,
txHash: receipt.transactionHash
})
});
const data = await response.json();
this.token = data.token;
return data.accountId;
}
async getAccount() {
const response = await fetch(`${this.serverUrl}/account`, {
headers: { 'Authorization': `Bearer ${this.token}` }
});
return await response.json();
}
}
// Minimal Contract ABI
const SBT_ABI = [
"function mintSBT(bytes32 eulaHash, uint8 version) returns (uint256, bytes32)",
"function getAccountInfo(address) view returns (bool, bytes32, uint256)"
];
// Usage example
async function example() {
const client = new SoulboundAuthClient({
serverUrl: 'http://localhost:3000',
sbtContract: '0x...'
});
// Connect and check status
const auth = await client.connect();
if (!auth.hasSBT) {
// Need to mint SBT
const eulaHash = ethers.utils.keccak256(
ethers.utils.toUtf8Bytes("Terms of Service v1.0")
);
const accountId = await client.mintSBT(eulaHash, 1);
console.log('Account created:', accountId);
} else {
console.log('Existing account:', auth.accountId);
}
// Get account details
const account = await client.getAccount();
console.log('Account info:', account);
}