@brainai/satp-client 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +529 -51
- package/examples/integration-patterns.js +495 -0
- package/examples/runtime-policy-adapter.js +75 -0
- package/examples/x402-discovery-evidence-lookup.js +66 -0
- package/package.json +42 -5
- package/src/attestation-request.js +149 -0
- package/src/borsh-reader.d.ts +213 -0
- package/src/borsh-reader.js +587 -0
- package/src/constants.js +10 -0
- package/src/index.d.ts +507 -0
- package/src/index.js +672 -0
- package/src/pda.js +43 -0
- package/src/runtime-policy-adapter.js +206 -0
- package/src/trust-packet.js +148 -0
- package/src/v3-pda.d.ts +72 -0
- package/src/v3-pda.js +281 -0
- package/src/v3-sdk.d.ts +508 -0
- package/src/v3-sdk.js +1800 -0
- package/src/wallet-control-challenge.js +351 -0
- package/src/x402-discovery.js +180 -0
package/src/v3-pda.js
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
const { PublicKey } = require('@solana/web3.js');
|
|
2
|
+
const crypto = require('crypto');
|
|
3
|
+
|
|
4
|
+
// ═══════════════════════════════════════════════════
|
|
5
|
+
// SATP V3 Program IDs — Devnet
|
|
6
|
+
// ═══════════════════════════════════════════════════
|
|
7
|
+
|
|
8
|
+
const V3_DEVNET_PROGRAM_IDS = {
|
|
9
|
+
IDENTITY: new PublicKey('GTppU4E44BqXTQgbqMZ68ozFzhP1TLty3EGnzzjtNZfG'),
|
|
10
|
+
REVIEWS: new PublicKey('r9XX4frcqxxAZ6Au9V5PA3EAxs1zoNckqLLmoSRcNr4'),
|
|
11
|
+
REPUTATION: new PublicKey('2Lz7KzMvKdrGeAuS8WPHu7jK2yScrnKVgacpYVEuDjkJ'),
|
|
12
|
+
ATTESTATIONS: new PublicKey('6Xd1dAQJPvQRJ4Ntr6LtPTjDjPUZ8nfnmYLZaZ2DtrdD'),
|
|
13
|
+
VALIDATION: new PublicKey('6rYRiCYidJYV7QvKrzKGgNu4oMh6BAvynked69R7xMbV'),
|
|
14
|
+
ESCROW: new PublicKey('HXCUWKR2NvRcZ7rNAJHwPcH6QAAWaLR4bRFbfyuDND6C'),
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const V3_MAINNET_PROGRAM_IDS = null;
|
|
18
|
+
|
|
19
|
+
// ═══════════════════════════════════════════════════
|
|
20
|
+
// V3 PDA Seeds — must match on-chain programs
|
|
21
|
+
// ═══════════════════════════════════════════════════
|
|
22
|
+
|
|
23
|
+
const V3_SEEDS = {
|
|
24
|
+
GENESIS: 'genesis',
|
|
25
|
+
REPUTATION_AUTHORITY: 'reputation_v3_authority',
|
|
26
|
+
VALIDATION_AUTHORITY: 'validation_v3_authority',
|
|
27
|
+
MINT_TRACKER: 'mint_tracker',
|
|
28
|
+
NAME_REGISTRY: 'name_registry',
|
|
29
|
+
LINKED_WALLET: 'linked_wallet',
|
|
30
|
+
REVIEW: 'review_v3',
|
|
31
|
+
REVIEW_COUNTER: 'review_counter_v3',
|
|
32
|
+
ATTESTATION: 'attestation_v3',
|
|
33
|
+
ESCROW_V3: 'escrow_v3',
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// ═══════════════════════════════════════════════════
|
|
37
|
+
// V3 Program ID Getter
|
|
38
|
+
// ═══════════════════════════════════════════════════
|
|
39
|
+
|
|
40
|
+
function getV3ProgramIds(network = 'devnet') {
|
|
41
|
+
if (network !== 'devnet' && network !== 'mainnet') {
|
|
42
|
+
throw new Error('Invalid network: expected devnet or mainnet');
|
|
43
|
+
}
|
|
44
|
+
if (network === 'mainnet') {
|
|
45
|
+
throw new Error('SATP V3 mainnet program IDs are not configured; use devnet or provide an approved mainnet decision packet before enabling mainnet');
|
|
46
|
+
}
|
|
47
|
+
return V3_DEVNET_PROGRAM_IDS;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// ═══════════════════════════════════════════════════
|
|
51
|
+
// Utility: Hash agent_id to 32-byte seed
|
|
52
|
+
// ═══════════════════════════════════════════════════
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Hash an agent_id string to 32-byte SHA-256 (matches on-chain solana_program::hash::hash).
|
|
56
|
+
* @param {string} agentId - Agent identifier string
|
|
57
|
+
* @returns {Buffer} 32-byte hash
|
|
58
|
+
*/
|
|
59
|
+
function hashAgentId(agentId) {
|
|
60
|
+
return crypto.createHash('sha256').update(agentId, 'utf8').digest();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Hash a name (lowercased) for name registry PDA.
|
|
65
|
+
* @param {string} name
|
|
66
|
+
* @returns {Buffer} 32-byte SHA-256 hash
|
|
67
|
+
*/
|
|
68
|
+
function hashName(name) {
|
|
69
|
+
return crypto.createHash('sha256').update(name.toLowerCase(), 'utf8').digest();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ═══════════════════════════════════════════════════
|
|
73
|
+
// V3 PDA Derivation Functions
|
|
74
|
+
// ═══════════════════════════════════════════════════
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Derive Genesis Record PDA.
|
|
78
|
+
* Seeds: ["genesis", agent_id_hash]
|
|
79
|
+
* @param {string|Buffer} agentIdOrHash - agent_id string or 32-byte hash
|
|
80
|
+
* @param {'mainnet'|'devnet'} network
|
|
81
|
+
* @returns {[PublicKey, number]} [pda, bump]
|
|
82
|
+
*/
|
|
83
|
+
function getGenesisPDA(agentIdOrHash, network = 'devnet') {
|
|
84
|
+
const hash = typeof agentIdOrHash === 'string'
|
|
85
|
+
? hashAgentId(agentIdOrHash)
|
|
86
|
+
: Buffer.from(agentIdOrHash);
|
|
87
|
+
const programIds = getV3ProgramIds(network);
|
|
88
|
+
return PublicKey.findProgramAddressSync(
|
|
89
|
+
[Buffer.from(V3_SEEDS.GENESIS), hash],
|
|
90
|
+
programIds.IDENTITY
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Derive Reputation V3 Authority PDA (CPI signer).
|
|
96
|
+
* Seeds: ["reputation_v3_authority"]
|
|
97
|
+
* @param {'mainnet'|'devnet'} network
|
|
98
|
+
* @returns {[PublicKey, number]}
|
|
99
|
+
*/
|
|
100
|
+
function getV3ReputationAuthorityPDA(network = 'devnet') {
|
|
101
|
+
const programIds = getV3ProgramIds(network);
|
|
102
|
+
return PublicKey.findProgramAddressSync(
|
|
103
|
+
[Buffer.from(V3_SEEDS.REPUTATION_AUTHORITY)],
|
|
104
|
+
programIds.REPUTATION
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Derive Validation V3 Authority PDA (CPI signer).
|
|
110
|
+
* Seeds: ["validation_v3_authority"]
|
|
111
|
+
* @param {'mainnet'|'devnet'} network
|
|
112
|
+
* @returns {[PublicKey, number]}
|
|
113
|
+
*/
|
|
114
|
+
function getV3ValidationAuthorityPDA(network = 'devnet') {
|
|
115
|
+
const programIds = getV3ProgramIds(network);
|
|
116
|
+
return PublicKey.findProgramAddressSync(
|
|
117
|
+
[Buffer.from(V3_SEEDS.VALIDATION_AUTHORITY)],
|
|
118
|
+
programIds.VALIDATION
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Derive MintTracker PDA.
|
|
124
|
+
* Seeds: ["mint_tracker", genesis_pda]
|
|
125
|
+
* @param {PublicKey|string} genesisPDA
|
|
126
|
+
* @param {'mainnet'|'devnet'} network
|
|
127
|
+
* @returns {[PublicKey, number]}
|
|
128
|
+
*/
|
|
129
|
+
function getV3MintTrackerPDA(genesisPDA, network = 'devnet') {
|
|
130
|
+
const genesisKey = new PublicKey(genesisPDA);
|
|
131
|
+
const programIds = getV3ProgramIds(network);
|
|
132
|
+
return PublicKey.findProgramAddressSync(
|
|
133
|
+
[Buffer.from(V3_SEEDS.MINT_TRACKER), genesisKey.toBuffer()],
|
|
134
|
+
programIds.IDENTITY
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Derive Name Registry PDA.
|
|
140
|
+
* Seeds: ["name_registry", name_hash]
|
|
141
|
+
* @param {string|Buffer} nameOrHash - Display name string or 32-byte hash
|
|
142
|
+
* @param {'mainnet'|'devnet'} network
|
|
143
|
+
* @returns {[PublicKey, number]}
|
|
144
|
+
*/
|
|
145
|
+
function getNameRegistryPDA(nameOrHash, network = 'devnet') {
|
|
146
|
+
const hash = typeof nameOrHash === 'string'
|
|
147
|
+
? hashName(nameOrHash)
|
|
148
|
+
: Buffer.from(nameOrHash);
|
|
149
|
+
const programIds = getV3ProgramIds(network);
|
|
150
|
+
return PublicKey.findProgramAddressSync(
|
|
151
|
+
[Buffer.from(V3_SEEDS.NAME_REGISTRY), hash],
|
|
152
|
+
programIds.IDENTITY
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Derive Linked Wallet PDA.
|
|
158
|
+
* Seeds: ["linked_wallet", genesis_pda, wallet]
|
|
159
|
+
* @param {PublicKey|string} genesisPDA
|
|
160
|
+
* @param {PublicKey|string} wallet
|
|
161
|
+
* @param {'mainnet'|'devnet'} network
|
|
162
|
+
* @returns {[PublicKey, number]}
|
|
163
|
+
*/
|
|
164
|
+
function getLinkedWalletPDA(genesisPDA, wallet, network = 'devnet') {
|
|
165
|
+
const genesisKey = new PublicKey(genesisPDA);
|
|
166
|
+
const walletKey = new PublicKey(wallet);
|
|
167
|
+
const programIds = getV3ProgramIds(network);
|
|
168
|
+
return PublicKey.findProgramAddressSync(
|
|
169
|
+
[Buffer.from(V3_SEEDS.LINKED_WALLET), genesisKey.toBuffer(), walletKey.toBuffer()],
|
|
170
|
+
programIds.IDENTITY
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Derive V3 Review PDA (agent-scoped).
|
|
176
|
+
* Seeds: ["review_v3", SHA256(agent_id), reviewer]
|
|
177
|
+
* @param {string|Buffer} agentIdOrHash - agent_id string or 32-byte hash
|
|
178
|
+
* @param {PublicKey|string} reviewer
|
|
179
|
+
* @param {'mainnet'|'devnet'} network
|
|
180
|
+
* @returns {[PublicKey, number]}
|
|
181
|
+
*/
|
|
182
|
+
function getV3ReviewPDA(agentIdOrHash, reviewer, network = 'devnet') {
|
|
183
|
+
const hash = typeof agentIdOrHash === 'string'
|
|
184
|
+
? hashAgentId(agentIdOrHash)
|
|
185
|
+
: Buffer.from(agentIdOrHash);
|
|
186
|
+
const reviewerKey = new PublicKey(reviewer);
|
|
187
|
+
const programIds = getV3ProgramIds(network);
|
|
188
|
+
return PublicKey.findProgramAddressSync(
|
|
189
|
+
[Buffer.from(V3_SEEDS.REVIEW), hash, reviewerKey.toBuffer()],
|
|
190
|
+
programIds.REVIEWS
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Derive V3 Review Counter PDA.
|
|
196
|
+
* Seeds: ["review_counter_v3", SHA256(agent_id)]
|
|
197
|
+
* @param {string|Buffer} agentIdOrHash - agent_id string or 32-byte hash
|
|
198
|
+
* @param {'mainnet'|'devnet'} network
|
|
199
|
+
* @returns {[PublicKey, number]}
|
|
200
|
+
*/
|
|
201
|
+
function getV3ReviewCounterPDA(agentIdOrHash, network = 'devnet') {
|
|
202
|
+
const hash = typeof agentIdOrHash === 'string'
|
|
203
|
+
? hashAgentId(agentIdOrHash)
|
|
204
|
+
: Buffer.from(agentIdOrHash);
|
|
205
|
+
const programIds = getV3ProgramIds(network);
|
|
206
|
+
return PublicKey.findProgramAddressSync(
|
|
207
|
+
[Buffer.from(V3_SEEDS.REVIEW_COUNTER), hash],
|
|
208
|
+
programIds.REVIEWS
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Derive V3 Attestation PDA.
|
|
214
|
+
* Seeds: ["attestation", agent_id_hash, attester, attestation_type]
|
|
215
|
+
* @param {string|Buffer} agentIdOrHash
|
|
216
|
+
* @param {PublicKey|string} attester
|
|
217
|
+
* @param {string} attestationType
|
|
218
|
+
* @param {'mainnet'|'devnet'} network
|
|
219
|
+
* @returns {[PublicKey, number]}
|
|
220
|
+
*/
|
|
221
|
+
function getV3AttestationPDA(agentIdOrHash, attester, attestationType, network = 'devnet') {
|
|
222
|
+
const hash = typeof agentIdOrHash === 'string'
|
|
223
|
+
? hashAgentId(agentIdOrHash)
|
|
224
|
+
: Buffer.from(agentIdOrHash);
|
|
225
|
+
const attesterKey = new PublicKey(attester);
|
|
226
|
+
const programIds = getV3ProgramIds(network);
|
|
227
|
+
return PublicKey.findProgramAddressSync(
|
|
228
|
+
[
|
|
229
|
+
Buffer.from(V3_SEEDS.ATTESTATION),
|
|
230
|
+
hash,
|
|
231
|
+
attesterKey.toBuffer(),
|
|
232
|
+
Buffer.from(attestationType, 'utf8'),
|
|
233
|
+
],
|
|
234
|
+
programIds.ATTESTATIONS
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Derive Escrow V3 PDA.
|
|
240
|
+
* Seeds: ["escrow_v3", client, description_hash, nonce_le_bytes]
|
|
241
|
+
* @param {PublicKey|string} client - Client wallet
|
|
242
|
+
* @param {Buffer} descriptionHash - 32-byte SHA-256 of job description
|
|
243
|
+
* @param {number|bigint} nonce - Unique nonce (u64)
|
|
244
|
+
* @param {'mainnet'|'devnet'} network
|
|
245
|
+
* @returns {[PublicKey, number]}
|
|
246
|
+
*/
|
|
247
|
+
function getV3EscrowPDA(client, descriptionHash, nonce, network = 'devnet') {
|
|
248
|
+
const clientKey = new PublicKey(client);
|
|
249
|
+
const hashBuf = Buffer.isBuffer(descriptionHash) ? descriptionHash : Buffer.from(descriptionHash);
|
|
250
|
+
const nonceBuf = Buffer.alloc(8);
|
|
251
|
+
nonceBuf.writeBigUInt64LE(BigInt(nonce));
|
|
252
|
+
const programIds = getV3ProgramIds(network);
|
|
253
|
+
return PublicKey.findProgramAddressSync(
|
|
254
|
+
[Buffer.from(V3_SEEDS.ESCROW_V3), clientKey.toBuffer(), hashBuf, nonceBuf],
|
|
255
|
+
programIds.ESCROW
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
module.exports = {
|
|
260
|
+
// Program IDs
|
|
261
|
+
V3_DEVNET_PROGRAM_IDS,
|
|
262
|
+
V3_MAINNET_PROGRAM_IDS,
|
|
263
|
+
getV3ProgramIds,
|
|
264
|
+
V3_SEEDS,
|
|
265
|
+
|
|
266
|
+
// Utilities
|
|
267
|
+
hashAgentId,
|
|
268
|
+
hashName,
|
|
269
|
+
|
|
270
|
+
// PDA derivation
|
|
271
|
+
getGenesisPDA,
|
|
272
|
+
getV3ReputationAuthorityPDA,
|
|
273
|
+
getV3ValidationAuthorityPDA,
|
|
274
|
+
getV3MintTrackerPDA,
|
|
275
|
+
getNameRegistryPDA,
|
|
276
|
+
getLinkedWalletPDA,
|
|
277
|
+
getV3ReviewPDA,
|
|
278
|
+
getV3ReviewCounterPDA,
|
|
279
|
+
getV3AttestationPDA,
|
|
280
|
+
getV3EscrowPDA,
|
|
281
|
+
};
|