-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlitAction-checkExpiration.js
More file actions
142 lines (119 loc) · 4.21 KB
/
litAction-checkExpiration.js
File metadata and controls
142 lines (119 loc) · 4.21 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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/**
* Lit Action for DeadManSwitch Expiration Check
*
* This Lit Action:
* 1. Fetches the raw account data for a DeadManSwitch PDA
* 2. Parses the account data according to the struct layout
* 3. Checks if the switch has expired based on last_ping + ping_interval
* 4. Returns true/false for access control
*/
const go = async () => {
// Switch PDA address to check (this would be passed as a parameter)
const switchPDA = "6WxoKuS16j8evGpQZt9MaKugFx3YCQ7vMmQN32UCj4Ep";
try {
// 1. Fetch account data from Solana
const rpcUrl = "https://api.devnet.solana.com";
const response = await fetch(rpcUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "getAccountInfo",
params: [
switchPDA,
{
encoding: "base64",
commitment: "confirmed"
}
]
})
});
const result = await response.json();
if (!result.result || !result.result.value) {
throw new Error("Account not found");
}
// 2. Parse the account data
const accountDataBase64 = result.result.value.data[0];
const accountDataBuffer = Uint8Array.from(atob(accountDataBase64), c => c.charCodeAt(0));
// Parse according to DeadManSwitch struct layout (correct offsets):
// After 8-byte Anchor discriminator:
// owner: Pubkey (32 bytes) - offset 0
// last_ping: i64 (8 bytes) - offset 32
// ping_interval: i64 (8 bytes) - offset 40
// encrypted_data: [u8; 512] (512 bytes) - offset 48
// data_length: u16 (2 bytes) - offset 560
// created_at: i64 (8 bytes) - offset 562
// bump: u8 (1 byte) - offset 570
function parseDeadManSwitch(buffer) {
let offset = 8; // Skip Anchor discriminator
// Skip owner (32 bytes)
offset += 32;
// Parse last_ping (8 bytes at offset 32, little-endian)
const lastPing = Number(
new DataView(buffer.buffer, buffer.byteOffset + offset, 8).getBigInt64(0, true)
);
offset += 8;
// Parse ping_interval (8 bytes at offset 40, little-endian)
const pingInterval = Number(
new DataView(buffer.buffer, buffer.byteOffset + offset, 8).getBigInt64(0, true)
);
offset += 8;
// Skip encrypted_data (512 bytes)
offset += 512;
// Parse data_length (2 bytes at offset 560, little-endian)
const dataLength = new DataView(buffer.buffer, buffer.byteOffset + offset, 2).getUint16(0, true);
offset += 2;
// Parse created_at (8 bytes at offset 562, little-endian)
const createdAt = Number(
new DataView(buffer.buffer, buffer.byteOffset + offset, 8).getBigInt64(0, true)
);
offset += 8;
// Parse bump (1 byte at offset 570)
const bump = new DataView(buffer.buffer, buffer.byteOffset + offset, 1).getUint8(0);
return {
lastPing,
pingInterval,
dataLength,
createdAt,
bump
};
}
const switchData = parseDeadManSwitch(accountDataBuffer);
// 3. Get current time (Unix timestamp in seconds)
const currentTime = Math.floor(Date.now() / 1000);
// 4. Calculate expiration
const expirationTime = switchData.lastPing + switchData.pingInterval;
const isExpired = currentTime >= expirationTime;
// 5. Log for debugging
console.log('Switch Data:', {
lastPing: switchData.lastPing,
pingInterval: switchData.pingInterval,
currentTime: currentTime,
expirationTime: expirationTime,
isExpired: isExpired
});
// 6. Return the result for Lit Protocol access control
LitActions.setResponse({
response: JSON.stringify({
expired: isExpired,
currentTime: currentTime,
expirationTime: expirationTime,
lastPing: switchData.lastPing,
pingInterval: switchData.pingInterval
})
});
} catch (error) {
console.error('Error in Lit Action:', error);
// On error, deny access by default
LitActions.setResponse({
response: JSON.stringify({
expired: false,
error: error.message
})
});
}
};
go();