@5ive-tech/sdk 1.1.21 → 1.1.22
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/dist/session/index.d.ts +41 -2
- package/dist/session/index.js +254 -52
- package/package.json +1 -1
package/dist/session/index.d.ts
CHANGED
|
@@ -9,21 +9,56 @@ export interface CreateSessionParams {
|
|
|
9
9
|
authority: string;
|
|
10
10
|
delegate: string;
|
|
11
11
|
targetProgram: string;
|
|
12
|
+
sessionAccount?: string;
|
|
12
13
|
expiresAtSlot: number;
|
|
13
14
|
scopeHash: string;
|
|
14
15
|
bindAccount?: string;
|
|
15
16
|
nonce?: number;
|
|
16
17
|
payer?: string;
|
|
18
|
+
rpcLabel?: string;
|
|
19
|
+
schemaPreference?: CreateSessionSchema | 'auto';
|
|
17
20
|
}
|
|
18
21
|
export interface RevokeSessionParams {
|
|
19
22
|
authority: string;
|
|
20
23
|
delegate: string;
|
|
21
24
|
targetProgram: string;
|
|
22
25
|
payer?: string;
|
|
26
|
+
rpcLabel?: string;
|
|
23
27
|
}
|
|
24
28
|
export interface CreateSessionCompatResult {
|
|
25
29
|
signature: string;
|
|
26
|
-
schema:
|
|
30
|
+
schema: CreateSessionSchema;
|
|
31
|
+
}
|
|
32
|
+
export type CreateSessionSchema = 'legacy' | 'minimal';
|
|
33
|
+
export interface SessionClientBuildContext {
|
|
34
|
+
operation: 'derive_session' | 'create_session' | 'revoke_session';
|
|
35
|
+
schema?: CreateSessionSchema;
|
|
36
|
+
managerScriptAccount: string;
|
|
37
|
+
vmProgramId: string;
|
|
38
|
+
sessionAddress?: string;
|
|
39
|
+
targetProgram?: string;
|
|
40
|
+
authority?: string;
|
|
41
|
+
delegate?: string;
|
|
42
|
+
rpcLabel?: string;
|
|
43
|
+
}
|
|
44
|
+
export declare class SessionClientBuildError extends Error {
|
|
45
|
+
readonly context: SessionClientBuildContext;
|
|
46
|
+
readonly cause?: unknown;
|
|
47
|
+
constructor(message: string, context: SessionClientBuildContext, cause?: unknown);
|
|
48
|
+
}
|
|
49
|
+
export interface BuildCreateSessionPlanOptions {
|
|
50
|
+
connection?: Connection;
|
|
51
|
+
payer?: PublicKey;
|
|
52
|
+
delegateMinLamports?: number;
|
|
53
|
+
delegateTopupLamports?: number;
|
|
54
|
+
rpcLabel?: string;
|
|
55
|
+
}
|
|
56
|
+
export interface CreateSessionPlan {
|
|
57
|
+
schema: CreateSessionSchema;
|
|
58
|
+
sessionAddress: string;
|
|
59
|
+
createSessionIx: TransactionInstruction;
|
|
60
|
+
createSessionAccountIx: TransactionInstruction | null;
|
|
61
|
+
topupDelegateIx: TransactionInstruction | null;
|
|
27
62
|
}
|
|
28
63
|
export declare function scopeHashForFunctions(functionNames: string[]): string;
|
|
29
64
|
export declare function canonicalSessionManagerScriptAccount(vmProgramId: string): string;
|
|
@@ -36,9 +71,13 @@ export declare class SessionClient {
|
|
|
36
71
|
});
|
|
37
72
|
static scopeHashForFunctions(functionNames: string[]): string;
|
|
38
73
|
static canonicalManagerScriptAccount(vmProgramId: string): string;
|
|
74
|
+
private buildError;
|
|
75
|
+
private createSessionSchemas;
|
|
39
76
|
deriveSessionAddress(authority: string, delegate: string, targetProgram: string): Promise<string>;
|
|
77
|
+
private buildCreateSessionCore;
|
|
40
78
|
createSessionIx(params: CreateSessionParams): Promise<TransactionInstruction>;
|
|
41
|
-
|
|
79
|
+
buildCreateSessionPlan(params: CreateSessionParams, options?: BuildCreateSessionPlanOptions): Promise<CreateSessionPlan>;
|
|
80
|
+
createSessionWithCompat(params: CreateSessionParams, send: (ix: TransactionInstruction, schema: CreateSessionSchema) => Promise<string>): Promise<CreateSessionCompatResult>;
|
|
42
81
|
revokeSessionIx(params: RevokeSessionParams): Promise<TransactionInstruction>;
|
|
43
82
|
prepareSessionAccountTx(input: {
|
|
44
83
|
connection: Connection;
|
package/dist/session/index.js
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { PublicKey, SystemProgram, TransactionInstruction } from '@solana/web3.js';
|
|
2
2
|
import { FiveProgram } from '../program/FiveProgram.js';
|
|
3
|
+
export class SessionClientBuildError extends Error {
|
|
4
|
+
constructor(message, context, cause) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = 'SessionClientBuildError';
|
|
7
|
+
this.context = context;
|
|
8
|
+
this.cause = cause;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
3
11
|
const SYSTEM_PROGRAM = '11111111111111111111111111111111';
|
|
4
12
|
const SESSION_MANAGER_ABI_MINIMAL = {
|
|
5
13
|
name: 'SessionManager',
|
|
@@ -36,6 +44,45 @@ const SESSION_MANAGER_ABI_MINIMAL = {
|
|
|
36
44
|
},
|
|
37
45
|
],
|
|
38
46
|
};
|
|
47
|
+
const SESSION_MANAGER_ABI_LEGACY = {
|
|
48
|
+
name: 'SessionManager',
|
|
49
|
+
functions: [
|
|
50
|
+
{
|
|
51
|
+
name: 'create_session',
|
|
52
|
+
index: 0,
|
|
53
|
+
parameters: [
|
|
54
|
+
{ name: 'session', type: 'Account', is_account: true, attributes: ['mut'] },
|
|
55
|
+
{ name: 'authority', type: 'Account', is_account: true, attributes: ['signer'] },
|
|
56
|
+
{ name: 'delegate', type: 'Account', is_account: true, attributes: [] },
|
|
57
|
+
{ name: 'target_program', type: 'pubkey', is_account: false, attributes: [] },
|
|
58
|
+
{ name: 'expires_at_slot', type: 'u64', is_account: false, attributes: [] },
|
|
59
|
+
{ name: 'scope_hash', type: 'u64', is_account: false, attributes: [] },
|
|
60
|
+
{ name: 'bind_account', type: 'pubkey', is_account: false, attributes: [] },
|
|
61
|
+
{ name: 'nonce', type: 'u64', is_account: false, attributes: [] },
|
|
62
|
+
{ name: 'manager_script_account', type: 'pubkey', is_account: false, attributes: [] },
|
|
63
|
+
{ name: 'manager_code_hash', type: 'pubkey', is_account: false, attributes: [] },
|
|
64
|
+
{ name: 'manager_version', type: 'u8', is_account: false, attributes: [] },
|
|
65
|
+
],
|
|
66
|
+
return_type: null,
|
|
67
|
+
visibility: 'public',
|
|
68
|
+
is_public: true,
|
|
69
|
+
bytecode_offset: 0,
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: 'revoke_session',
|
|
73
|
+
index: 1,
|
|
74
|
+
parameters: [
|
|
75
|
+
{ name: 'session', type: 'Account', is_account: true, attributes: ['mut'] },
|
|
76
|
+
{ name: 'authority', type: 'Account', is_account: true, attributes: ['signer'] },
|
|
77
|
+
],
|
|
78
|
+
return_type: null,
|
|
79
|
+
visibility: 'public',
|
|
80
|
+
is_public: true,
|
|
81
|
+
bytecode_offset: 0,
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
};
|
|
85
|
+
const DEFAULT_CREATE_SESSION_SCHEMA = 'legacy';
|
|
39
86
|
export function scopeHashForFunctions(functionNames) {
|
|
40
87
|
const sorted = [...functionNames].sort();
|
|
41
88
|
let acc = 0n;
|
|
@@ -61,67 +108,222 @@ export class SessionClient {
|
|
|
61
108
|
static canonicalManagerScriptAccount(vmProgramId) {
|
|
62
109
|
return canonicalSessionManagerScriptAccount(vmProgramId);
|
|
63
110
|
}
|
|
111
|
+
buildError(message, context, cause) {
|
|
112
|
+
return new SessionClientBuildError(message, context, cause);
|
|
113
|
+
}
|
|
114
|
+
createSessionSchemas(preference) {
|
|
115
|
+
if (preference === 'minimal')
|
|
116
|
+
return ['minimal'];
|
|
117
|
+
if (preference === 'legacy')
|
|
118
|
+
return ['legacy'];
|
|
119
|
+
return [DEFAULT_CREATE_SESSION_SCHEMA, 'minimal'].filter((schema, index, all) => all.indexOf(schema) === index);
|
|
120
|
+
}
|
|
64
121
|
async deriveSessionAddress(authority, delegate, targetProgram) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
122
|
+
try {
|
|
123
|
+
const [session] = await FiveProgram.fromABI(this.managerScriptAccount, SESSION_MANAGER_ABI_MINIMAL, {
|
|
124
|
+
fiveVMProgramId: this.vmProgramId,
|
|
125
|
+
}).findAddress(['session', authority, delegate, targetProgram], this.vmProgramId);
|
|
126
|
+
return session;
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
throw this.buildError('Failed to derive canonical session address', {
|
|
130
|
+
operation: 'derive_session',
|
|
131
|
+
managerScriptAccount: this.managerScriptAccount,
|
|
132
|
+
vmProgramId: this.vmProgramId,
|
|
133
|
+
authority,
|
|
134
|
+
delegate,
|
|
135
|
+
targetProgram,
|
|
136
|
+
}, error);
|
|
137
|
+
}
|
|
69
138
|
}
|
|
70
|
-
async
|
|
71
|
-
const
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
};
|
|
82
|
-
const builder = program
|
|
83
|
-
.function('create_session')
|
|
84
|
-
.accounts({
|
|
85
|
-
session,
|
|
139
|
+
async buildCreateSessionCore(params, schema) {
|
|
140
|
+
const sessionAddress = await this.deriveSessionAddress(params.authority, params.delegate, params.targetProgram);
|
|
141
|
+
const resolvedSessionAddress = schema === 'legacy' && params.sessionAccount
|
|
142
|
+
? params.sessionAccount
|
|
143
|
+
: sessionAddress;
|
|
144
|
+
const contextBase = {
|
|
145
|
+
operation: 'create_session',
|
|
146
|
+
schema,
|
|
147
|
+
managerScriptAccount: this.managerScriptAccount,
|
|
148
|
+
vmProgramId: this.vmProgramId,
|
|
149
|
+
sessionAddress: resolvedSessionAddress,
|
|
86
150
|
authority: params.authority,
|
|
87
151
|
delegate: params.delegate,
|
|
88
|
-
|
|
89
|
-
.
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
152
|
+
targetProgram: params.targetProgram,
|
|
153
|
+
rpcLabel: params.rpcLabel,
|
|
154
|
+
};
|
|
155
|
+
try {
|
|
156
|
+
const program = FiveProgram.fromABI(this.managerScriptAccount, schema === 'legacy' ? SESSION_MANAGER_ABI_LEGACY : SESSION_MANAGER_ABI_MINIMAL, {
|
|
157
|
+
fiveVMProgramId: this.vmProgramId,
|
|
158
|
+
});
|
|
159
|
+
const argMap = {
|
|
160
|
+
target_program: params.targetProgram,
|
|
161
|
+
expires_at_slot: params.expiresAtSlot,
|
|
162
|
+
scope_hash: params.scopeHash,
|
|
163
|
+
bind_account: params.bindAccount || SYSTEM_PROGRAM,
|
|
164
|
+
nonce: params.nonce ?? 0,
|
|
165
|
+
};
|
|
166
|
+
if (schema === 'legacy') {
|
|
167
|
+
argMap.manager_script_account = this.managerScriptAccount;
|
|
168
|
+
argMap.manager_code_hash = SYSTEM_PROGRAM;
|
|
169
|
+
argMap.manager_version = 1;
|
|
170
|
+
}
|
|
171
|
+
const builder = program
|
|
172
|
+
.function('create_session')
|
|
173
|
+
.accounts({
|
|
174
|
+
session: resolvedSessionAddress,
|
|
175
|
+
authority: params.authority,
|
|
176
|
+
delegate: params.delegate,
|
|
177
|
+
})
|
|
178
|
+
.args(argMap);
|
|
179
|
+
builder.payer(params.payer || params.authority);
|
|
180
|
+
const encoded = await builder.instruction();
|
|
181
|
+
return {
|
|
182
|
+
schema,
|
|
183
|
+
sessionAddress: resolvedSessionAddress,
|
|
184
|
+
instruction: new TransactionInstruction({
|
|
185
|
+
programId: new PublicKey(encoded.programId),
|
|
186
|
+
keys: encoded.keys.map((k) => ({
|
|
187
|
+
pubkey: new PublicKey(k.pubkey),
|
|
188
|
+
isSigner: k.isSigner,
|
|
189
|
+
isWritable: k.isWritable,
|
|
190
|
+
})),
|
|
191
|
+
data: Buffer.from(encoded.data, 'base64'),
|
|
192
|
+
}),
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
throw this.buildError('Failed to build create_session instruction', contextBase, error);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
async createSessionIx(params) {
|
|
200
|
+
const schema = this.createSessionSchemas(params.schemaPreference)[0];
|
|
201
|
+
const built = await this.buildCreateSessionCore(params, schema);
|
|
202
|
+
return built.instruction;
|
|
203
|
+
}
|
|
204
|
+
async buildCreateSessionPlan(params, options = {}) {
|
|
205
|
+
const schema = this.createSessionSchemas(params.schemaPreference)[0];
|
|
206
|
+
const built = await this.buildCreateSessionCore(params, schema);
|
|
207
|
+
let createSessionAccountIx = null;
|
|
208
|
+
let topupDelegateIx = null;
|
|
209
|
+
if (options.connection && options.payer && schema === 'legacy' && params.sessionAccount) {
|
|
210
|
+
try {
|
|
211
|
+
const prepared = await this.prepareSessionAccountTx({
|
|
212
|
+
connection: options.connection,
|
|
213
|
+
payer: options.payer,
|
|
214
|
+
sessionAccount: new PublicKey(params.sessionAccount),
|
|
215
|
+
delegate: new PublicKey(params.delegate),
|
|
216
|
+
delegateMinLamports: options.delegateMinLamports,
|
|
217
|
+
delegateTopupLamports: options.delegateTopupLamports,
|
|
218
|
+
});
|
|
219
|
+
createSessionAccountIx = prepared.createIx;
|
|
220
|
+
topupDelegateIx = prepared.topupIx;
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
throw this.buildError('Failed while building session account setup instructions for create_session', {
|
|
224
|
+
operation: 'create_session',
|
|
225
|
+
schema,
|
|
226
|
+
managerScriptAccount: this.managerScriptAccount,
|
|
227
|
+
vmProgramId: this.vmProgramId,
|
|
228
|
+
sessionAddress: built.sessionAddress,
|
|
229
|
+
authority: params.authority,
|
|
230
|
+
delegate: params.delegate,
|
|
231
|
+
targetProgram: params.targetProgram,
|
|
232
|
+
rpcLabel: options.rpcLabel || params.rpcLabel,
|
|
233
|
+
}, error);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
else if (options.connection &&
|
|
237
|
+
options.payer &&
|
|
238
|
+
options.delegateMinLamports &&
|
|
239
|
+
options.delegateTopupLamports) {
|
|
240
|
+
try {
|
|
241
|
+
const delegateBalance = await options.connection.getBalance(new PublicKey(params.delegate), 'confirmed');
|
|
242
|
+
if (delegateBalance < options.delegateMinLamports) {
|
|
243
|
+
topupDelegateIx = SystemProgram.transfer({
|
|
244
|
+
fromPubkey: options.payer,
|
|
245
|
+
toPubkey: new PublicKey(params.delegate),
|
|
246
|
+
lamports: options.delegateTopupLamports,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
throw this.buildError('Failed while building delegate funding instruction for create_session', {
|
|
252
|
+
operation: 'create_session',
|
|
253
|
+
schema,
|
|
254
|
+
managerScriptAccount: this.managerScriptAccount,
|
|
255
|
+
vmProgramId: this.vmProgramId,
|
|
256
|
+
sessionAddress: built.sessionAddress,
|
|
257
|
+
authority: params.authority,
|
|
258
|
+
delegate: params.delegate,
|
|
259
|
+
targetProgram: params.targetProgram,
|
|
260
|
+
rpcLabel: options.rpcLabel || params.rpcLabel,
|
|
261
|
+
}, error);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return {
|
|
265
|
+
schema,
|
|
266
|
+
sessionAddress: built.sessionAddress,
|
|
267
|
+
createSessionIx: built.instruction,
|
|
268
|
+
createSessionAccountIx,
|
|
269
|
+
topupDelegateIx,
|
|
270
|
+
};
|
|
101
271
|
}
|
|
102
272
|
async createSessionWithCompat(params, send) {
|
|
103
|
-
const
|
|
104
|
-
|
|
273
|
+
const attempts = this.createSessionSchemas(params.schemaPreference);
|
|
274
|
+
let lastError = null;
|
|
275
|
+
for (const schema of attempts) {
|
|
276
|
+
try {
|
|
277
|
+
const built = await this.buildCreateSessionCore(params, schema);
|
|
278
|
+
return { signature: await send(built.instruction, schema), schema };
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
lastError = error;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
throw this.buildError('All create_session schema attempts failed', {
|
|
285
|
+
operation: 'create_session',
|
|
286
|
+
managerScriptAccount: this.managerScriptAccount,
|
|
287
|
+
vmProgramId: this.vmProgramId,
|
|
288
|
+
authority: params.authority,
|
|
289
|
+
delegate: params.delegate,
|
|
290
|
+
targetProgram: params.targetProgram,
|
|
291
|
+
rpcLabel: params.rpcLabel,
|
|
292
|
+
}, lastError);
|
|
105
293
|
}
|
|
106
294
|
async revokeSessionIx(params) {
|
|
107
295
|
const session = await this.deriveSessionAddress(params.authority, params.delegate, params.targetProgram);
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
296
|
+
try {
|
|
297
|
+
const program = FiveProgram.fromABI(this.managerScriptAccount, SESSION_MANAGER_ABI_MINIMAL, {
|
|
298
|
+
fiveVMProgramId: this.vmProgramId,
|
|
299
|
+
});
|
|
300
|
+
const builder = program
|
|
301
|
+
.function('revoke_session')
|
|
302
|
+
.accounts({ session, authority: params.authority });
|
|
303
|
+
builder.payer(params.payer || params.authority);
|
|
304
|
+
const encoded = await builder.instruction();
|
|
305
|
+
return new TransactionInstruction({
|
|
306
|
+
programId: new PublicKey(encoded.programId),
|
|
307
|
+
keys: encoded.keys.map((k) => ({
|
|
308
|
+
pubkey: new PublicKey(k.pubkey),
|
|
309
|
+
isSigner: k.isSigner,
|
|
310
|
+
isWritable: k.isWritable,
|
|
311
|
+
})),
|
|
312
|
+
data: Buffer.from(encoded.data, 'base64'),
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
catch (error) {
|
|
316
|
+
throw this.buildError('Failed to build revoke_session instruction', {
|
|
317
|
+
operation: 'revoke_session',
|
|
318
|
+
managerScriptAccount: this.managerScriptAccount,
|
|
319
|
+
vmProgramId: this.vmProgramId,
|
|
320
|
+
sessionAddress: session,
|
|
321
|
+
authority: params.authority,
|
|
322
|
+
delegate: params.delegate,
|
|
323
|
+
targetProgram: params.targetProgram,
|
|
324
|
+
rpcLabel: params.rpcLabel,
|
|
325
|
+
}, error);
|
|
326
|
+
}
|
|
125
327
|
}
|
|
126
328
|
async prepareSessionAccountTx(input) {
|
|
127
329
|
const sessionSpace = input.sessionSpace ?? 256;
|