@dexterai/vault 0.3.0 → 0.3.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.
@@ -112,408 +112,19 @@ function buildSetSwigInstruction(p) {
112
112
 
113
113
  // src/instructions/setSwigAtomic.ts
114
114
  import {
115
+ PublicKey as PublicKey5,
115
116
  TransactionInstruction as TransactionInstruction3,
116
117
  SystemProgram as SystemProgram2,
117
118
  SYSVAR_INSTRUCTIONS_PUBKEY as SYSVAR_INSTRUCTIONS_PUBKEY2
118
119
  } from "@solana/web3.js";
119
- var SET_SWIG_ATOMIC_DISCRIMINATOR = new Uint8Array([
120
- 119,
121
- 111,
122
- 247,
123
- 215,
124
- 190,
125
- 3,
126
- 170,
127
- 23
128
- ]);
129
- function buildSetSwigAtomicInstruction(params) {
130
- if (params.swigId.length !== 32) {
131
- throw new Error(`swigId must be 32 bytes, got ${params.swigId.length}`);
132
- }
133
- if (params.authenticatorData.length < 37) {
134
- throw new Error(`authenticatorData must be at least 37 bytes`);
135
- }
136
- const cdj = params.clientDataJSON;
137
- const ad = params.authenticatorData;
138
- const dataLen = 8 + // discriminator
139
- 32 + // swig_id
140
- 1 + // swig_account_bump
141
- 1 + // swig_wallet_address_bump
142
- 32 + // dexter_master_pubkey
143
- 4 + cdj.length + // client_data_json (len-prefixed)
144
- 4 + ad.length;
145
- const data = new Uint8Array(dataLen);
146
- const view = new DataView(data.buffer);
147
- let off = 0;
148
- data.set(SET_SWIG_ATOMIC_DISCRIMINATOR, off);
149
- off += 8;
150
- data.set(params.swigId, off);
151
- off += 32;
152
- data[off++] = params.swigAccountBump;
153
- data[off++] = params.swigWalletAddressBump;
154
- data.set(params.dexterMasterPubkey.toBytes(), off);
155
- off += 32;
156
- view.setUint32(off, cdj.length, true);
157
- off += 4;
158
- data.set(cdj, off);
159
- off += cdj.length;
160
- view.setUint32(off, ad.length, true);
161
- off += 4;
162
- data.set(ad, off);
163
- off += ad.length;
164
- if (off !== dataLen) throw new Error(`internal: byte offset mismatch (${off} vs ${dataLen})`);
165
- return new TransactionInstruction3({
166
- programId: DEXTER_VAULT_PROGRAM_ID,
167
- keys: [
168
- { pubkey: params.vaultPda, isSigner: false, isWritable: true },
169
- { pubkey: params.feePayer, isSigner: true, isWritable: true },
170
- { pubkey: params.swigAddress, isSigner: false, isWritable: true },
171
- { pubkey: params.swigWalletAddress, isSigner: false, isWritable: true },
172
- { pubkey: SWIG_PROGRAM_ID, isSigner: false, isWritable: false },
173
- { pubkey: SystemProgram2.programId, isSigner: false, isWritable: false },
174
- { pubkey: SYSVAR_INSTRUCTIONS_PUBKEY2, isSigner: false, isWritable: false }
175
- ],
176
- data: Buffer.from(data)
177
- });
178
- }
179
-
180
- // src/instructions/registerSession.ts
181
- import { TransactionInstruction as TransactionInstruction4 } from "@solana/web3.js";
182
- function encodeU64LE(value) {
183
- const buf = new Uint8Array(8);
184
- new DataView(buf.buffer).setBigUint64(0, value, true);
185
- return buf;
186
- }
187
- function encodeI64LE(value) {
188
- const buf = new Uint8Array(8);
189
- new DataView(buf.buffer).setBigInt64(0, value, true);
190
- return buf;
191
- }
192
- function encodeU32LE(value) {
193
- const buf = new Uint8Array(4);
194
- new DataView(buf.buffer).setUint32(0, value >>> 0, true);
195
- return buf;
196
- }
197
- function encodeVecU8(bytes) {
198
- const out = new Uint8Array(4 + bytes.length);
199
- new DataView(out.buffer).setUint32(0, bytes.length >>> 0, true);
200
- out.set(bytes, 4);
201
- return out;
202
- }
203
- function concatBytes(...parts) {
204
- const total = parts.reduce((n, p) => n + p.length, 0);
205
- const out = new Uint8Array(total);
206
- let o2 = 0;
207
- for (const p of parts) {
208
- out.set(p, o2);
209
- o2 += p.length;
210
- }
211
- return out;
212
- }
213
- function buildRegisterSessionKeyInstruction(args) {
214
- if (args.sessionPubkey.length !== 32) {
215
- throw new Error(`sessionPubkey must be 32 bytes, got ${args.sessionPubkey.length}`);
216
- }
217
- const data = concatBytes(
218
- DISCRIMINATORS.register_session_key,
219
- args.sessionPubkey,
220
- encodeU64LE(args.maxAmount),
221
- encodeI64LE(args.expiresAt),
222
- args.allowedCounterparty.toBytes(),
223
- encodeU32LE(args.nonce),
224
- encodeVecU8(args.clientDataJSON),
225
- encodeVecU8(args.authenticatorData)
226
- );
227
- return new TransactionInstruction4({
228
- keys: [
229
- { pubkey: args.vaultPda, isSigner: false, isWritable: true },
230
- { pubkey: INSTRUCTIONS_SYSVAR_ID, isSigner: false, isWritable: false }
231
- ],
232
- programId: DEXTER_VAULT_PROGRAM_ID,
233
- data: Buffer.from(data)
234
- });
235
- }
236
-
237
- // src/instructions/revokeSession.ts
238
- import { TransactionInstruction as TransactionInstruction5 } from "@solana/web3.js";
239
- function encodeVecU82(bytes) {
240
- const out = new Uint8Array(4 + bytes.length);
241
- new DataView(out.buffer).setUint32(0, bytes.length >>> 0, true);
242
- out.set(bytes, 4);
243
- return out;
244
- }
245
- function concatBytes2(...parts) {
246
- const total = parts.reduce((n, p) => n + p.length, 0);
247
- const out = new Uint8Array(total);
248
- let o2 = 0;
249
- for (const p of parts) {
250
- out.set(p, o2);
251
- o2 += p.length;
252
- }
253
- return out;
254
- }
255
- function buildRevokeSessionKeyInstruction(args) {
256
- const data = concatBytes2(
257
- DISCRIMINATORS.revoke_session_key,
258
- encodeVecU82(args.clientDataJSON),
259
- encodeVecU82(args.authenticatorData)
260
- );
261
- return new TransactionInstruction5({
262
- keys: [
263
- { pubkey: args.vaultPda, isSigner: false, isWritable: true },
264
- { pubkey: INSTRUCTIONS_SYSVAR_ID, isSigner: false, isWritable: false }
265
- ],
266
- programId: DEXTER_VAULT_PROGRAM_ID,
267
- data: Buffer.from(data)
268
- });
269
- }
270
-
271
- // src/instructions/settleVoucher.ts
272
- import { TransactionInstruction as TransactionInstruction6 } from "@solana/web3.js";
273
- function encodeU64(value) {
274
- const out = Buffer.alloc(8);
275
- out.writeBigUInt64LE(value, 0);
276
- return out;
277
- }
278
- function encodeBool(value) {
279
- return Buffer.from([value ? 1 : 0]);
280
- }
281
- function buildSettleVoucherInstruction(p) {
282
- const argsBuf = Buffer.concat([encodeU64(p.amount), encodeBool(p.increment)]);
283
- const data = Buffer.concat([Buffer.from(DISCRIMINATORS.settle_voucher), argsBuf]);
284
- return new TransactionInstruction6({
285
- programId: DEXTER_VAULT_PROGRAM_ID,
286
- keys: [
287
- { pubkey: p.vaultPda, isSigner: false, isWritable: true },
288
- { pubkey: p.dexterAuthority, isSigner: true, isWritable: false }
289
- ],
290
- data
291
- });
292
- }
293
120
 
294
- // src/instructions/settleTabVoucher.ts
121
+ // src/instructions/swigBundle.ts
122
+ import { createHmac } from "crypto";
295
123
  import {
296
- TransactionInstruction as TransactionInstruction8,
297
- SYSVAR_INSTRUCTIONS_PUBKEY as SYSVAR_INSTRUCTIONS_PUBKEY4
298
- } from "@solana/web3.js";
299
-
300
- // src/instructions/withdraw.ts
301
- import {
302
- PublicKey as PublicKey8,
303
- TransactionInstruction as TransactionInstruction7,
304
- SYSVAR_INSTRUCTIONS_PUBKEY as SYSVAR_INSTRUCTIONS_PUBKEY3
305
- } from "@solana/web3.js";
306
- function encodeBytesVec2(buf) {
307
- const out = Buffer.alloc(4 + buf.length);
308
- out.writeUInt32LE(buf.length, 0);
309
- Buffer.from(buf).copy(out, 4);
310
- return out;
311
- }
312
- function encodeU642(value) {
313
- const out = Buffer.alloc(8);
314
- out.writeBigUInt64LE(value, 0);
315
- return out;
316
- }
317
- function encodeI64(value) {
318
- const out = Buffer.alloc(8);
319
- out.writeBigInt64LE(value, 0);
320
- return out;
321
- }
322
- function encodePubkey2(key) {
323
- return Buffer.from(key.toBytes());
324
- }
325
- function deriveSwigWalletAddress(swigAddress) {
326
- const [pda] = PublicKey8.findProgramAddressSync(
327
- [Buffer.from("swig-wallet-address"), swigAddress.toBuffer()],
328
- SWIG_PROGRAM_ID
329
- );
330
- return pda;
331
- }
332
- function buildRequestWithdrawalInstruction(p) {
333
- const argsBuf = Buffer.concat([
334
- encodeU642(p.amount),
335
- encodePubkey2(p.destination),
336
- encodeI64(p.signedAt),
337
- encodeBytesVec2(p.clientDataJSON),
338
- encodeBytesVec2(p.authenticatorData)
339
- ]);
340
- const data = Buffer.concat([Buffer.from(DISCRIMINATORS.request_withdrawal), argsBuf]);
341
- return new TransactionInstruction7({
342
- programId: DEXTER_VAULT_PROGRAM_ID,
343
- keys: [
344
- { pubkey: p.vaultPda, isSigner: false, isWritable: true },
345
- { pubkey: SYSVAR_INSTRUCTIONS_PUBKEY3, isSigner: false, isWritable: false }
346
- ],
347
- data
348
- });
349
- }
350
- function buildFinalizeWithdrawalInstruction(p) {
351
- const argsBuf = Buffer.concat([
352
- encodeBytesVec2(p.clientDataJSON),
353
- encodeBytesVec2(p.authenticatorData)
354
- ]);
355
- const data = Buffer.concat([Buffer.from(DISCRIMINATORS.finalize_withdrawal), argsBuf]);
356
- const swigWalletAddress = deriveSwigWalletAddress(p.swigAddress);
357
- return new TransactionInstruction7({
358
- programId: DEXTER_VAULT_PROGRAM_ID,
359
- keys: [
360
- { pubkey: p.swigAddress, isSigner: false, isWritable: false },
361
- { pubkey: swigWalletAddress, isSigner: false, isWritable: false },
362
- { pubkey: p.vaultPda, isSigner: false, isWritable: true },
363
- { pubkey: SYSVAR_INSTRUCTIONS_PUBKEY3, isSigner: false, isWritable: false }
364
- ],
365
- data
366
- });
367
- }
368
- function buildForceReleaseInstruction(p) {
369
- const argsBuf = Buffer.concat([
370
- encodeBytesVec2(p.clientDataJSON),
371
- encodeBytesVec2(p.authenticatorData)
372
- ]);
373
- const data = Buffer.concat([Buffer.from(DISCRIMINATORS.force_release), argsBuf]);
374
- return new TransactionInstruction7({
375
- programId: DEXTER_VAULT_PROGRAM_ID,
376
- keys: [
377
- { pubkey: p.vaultPda, isSigner: false, isWritable: true },
378
- { pubkey: SYSVAR_INSTRUCTIONS_PUBKEY3, isSigner: false, isWritable: false }
379
- ],
380
- data
381
- });
382
- }
383
-
384
- // src/instructions/settleTabVoucher.ts
385
- function encodeFixedBytes2(buf, len) {
386
- if (buf.length !== len) {
387
- throw new Error(`expected ${len} bytes, got ${buf.length}`);
388
- }
389
- return Buffer.from(buf);
390
- }
391
- function encodeU643(value) {
392
- const out = Buffer.alloc(8);
393
- out.writeBigUInt64LE(value, 0);
394
- return out;
395
- }
396
- function encodeU322(value) {
397
- const out = Buffer.alloc(4);
398
- out.writeUInt32LE(value >>> 0, 0);
399
- return out;
400
- }
401
- function buildSettleTabVoucherInstruction(p) {
402
- if (p.channelId.length !== 32) {
403
- throw new Error(`channelId must be 32 bytes, got ${p.channelId.length}`);
404
- }
405
- const argsBuf = Buffer.concat([
406
- encodeFixedBytes2(p.channelId, 32),
407
- encodeU643(p.cumulativeAmount),
408
- encodeU322(p.sequenceNumber)
409
- ]);
410
- const data = Buffer.concat([Buffer.from(DISCRIMINATORS.settle_tab_voucher), argsBuf]);
411
- const swigWalletAddress = deriveSwigWalletAddress(p.swigAddress);
412
- return new TransactionInstruction8({
413
- programId: DEXTER_VAULT_PROGRAM_ID,
414
- keys: [
415
- { pubkey: p.swigAddress, isSigner: false, isWritable: false },
416
- { pubkey: swigWalletAddress, isSigner: false, isWritable: false },
417
- { pubkey: p.vaultPda, isSigner: false, isWritable: true },
418
- { pubkey: p.dexterAuthority, isSigner: true, isWritable: false },
419
- { pubkey: SYSVAR_INSTRUCTIONS_PUBKEY4, isSigner: false, isWritable: false }
420
- ],
421
- data
422
- });
423
- }
424
-
425
- // src/instructions/rotate.ts
426
- import {
427
- TransactionInstruction as TransactionInstruction9,
428
- SYSVAR_INSTRUCTIONS_PUBKEY as SYSVAR_INSTRUCTIONS_PUBKEY5
429
- } from "@solana/web3.js";
430
- function encodeBytesVec3(buf) {
431
- const out = Buffer.alloc(4 + buf.length);
432
- out.writeUInt32LE(buf.length, 0);
433
- Buffer.from(buf).copy(out, 4);
434
- return out;
435
- }
436
- function encodeFixedBytes3(buf, len) {
437
- if (buf.length !== len) {
438
- throw new Error(`expected ${len} bytes, got ${buf.length}`);
439
- }
440
- return Buffer.from(buf);
441
- }
442
- function encodePubkey3(key) {
443
- return Buffer.from(key.toBytes());
444
- }
445
- function buildRotatePasskeyInstruction(p) {
446
- const argsBuf = Buffer.concat([
447
- encodeFixedBytes3(p.newPasskeyPubkey, 33),
448
- encodeBytesVec3(p.clientDataJSON),
449
- encodeBytesVec3(p.authenticatorData)
450
- ]);
451
- const data = Buffer.concat([Buffer.from(DISCRIMINATORS.rotate_passkey), argsBuf]);
452
- return new TransactionInstruction9({
453
- programId: DEXTER_VAULT_PROGRAM_ID,
454
- keys: [
455
- { pubkey: p.vaultPda, isSigner: false, isWritable: true },
456
- { pubkey: SYSVAR_INSTRUCTIONS_PUBKEY5, isSigner: false, isWritable: false }
457
- ],
458
- data
459
- });
460
- }
461
- function buildRotateDexterAuthorityInstruction(p) {
462
- const data = Buffer.concat([
463
- Buffer.from(DISCRIMINATORS.rotate_dexter_authority),
464
- encodePubkey3(p.newDexterAuthority)
465
- ]);
466
- return new TransactionInstruction9({
467
- programId: DEXTER_VAULT_PROGRAM_ID,
468
- keys: [
469
- { pubkey: p.vaultPda, isSigner: false, isWritable: true },
470
- { pubkey: p.currentDexterAuthority, isSigner: true, isWritable: false }
471
- ],
472
- data
473
- });
474
- }
475
-
476
- // src/instructions/provePasskey.ts
477
- import {
478
- TransactionInstruction as TransactionInstruction10,
479
- SYSVAR_INSTRUCTIONS_PUBKEY as SYSVAR_INSTRUCTIONS_PUBKEY6
480
- } from "@solana/web3.js";
481
- function encodeBytesVec4(buf) {
482
- const out = Buffer.alloc(4 + buf.length);
483
- out.writeUInt32LE(buf.length, 0);
484
- Buffer.from(buf).copy(out, 4);
485
- return out;
486
- }
487
- function encodeFixedBytes4(buf, len) {
488
- if (buf.length !== len) {
489
- throw new Error(`expected ${len} bytes, got ${buf.length}`);
490
- }
491
- return Buffer.from(buf);
492
- }
493
- function buildProvePasskeyInstruction(p) {
494
- const argsBuf = Buffer.concat([
495
- encodeFixedBytes4(p.challenge, 32),
496
- encodeBytesVec4(p.clientDataJSON),
497
- encodeBytesVec4(p.authenticatorData)
498
- ]);
499
- const data = Buffer.concat([Buffer.from(DISCRIMINATORS.prove_passkey), argsBuf]);
500
- return new TransactionInstruction10({
501
- programId: DEXTER_VAULT_PROGRAM_ID,
502
- keys: [
503
- { pubkey: p.vaultPda, isSigner: false, isWritable: false },
504
- { pubkey: SYSVAR_INSTRUCTIONS_PUBKEY6, isSigner: false, isWritable: false }
505
- ],
506
- data
507
- });
508
- }
509
-
510
- // src/instructions/swigBundle.ts
511
- import { createHmac } from "crypto";
512
- import {
513
- getInstructionsFromContext,
514
- findSwigPda,
515
- fetchNullableSwig
516
- } from "@swig-wallet/kit";
124
+ getInstructionsFromContext,
125
+ findSwigPda,
126
+ fetchNullableSwig
127
+ } from "@swig-wallet/kit";
517
128
  import {
518
129
  Actions,
519
130
  createProgramExecAuthorityInfo,
@@ -4395,643 +4006,1060 @@ function getHumanReadableErrorMessage5(code, context = {}) {
4395
4006
  if (messageFormatString.length === 0) {
4396
4007
  return "";
4397
4008
  }
4398
- let state;
4399
- function commitStateUpTo(endIndex) {
4400
- if (state[TYPE5] === 2) {
4401
- const variableName = messageFormatString.slice(state[START_INDEX5] + 1, endIndex);
4402
- fragments.push(
4403
- variableName in context ? (
4404
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
4405
- `${context[variableName]}`
4406
- ) : `$${variableName}`
4407
- );
4408
- } else if (state[TYPE5] === 1) {
4409
- fragments.push(messageFormatString.slice(state[START_INDEX5], endIndex));
4009
+ let state;
4010
+ function commitStateUpTo(endIndex) {
4011
+ if (state[TYPE5] === 2) {
4012
+ const variableName = messageFormatString.slice(state[START_INDEX5] + 1, endIndex);
4013
+ fragments.push(
4014
+ variableName in context ? (
4015
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
4016
+ `${context[variableName]}`
4017
+ ) : `$${variableName}`
4018
+ );
4019
+ } else if (state[TYPE5] === 1) {
4020
+ fragments.push(messageFormatString.slice(state[START_INDEX5], endIndex));
4021
+ }
4022
+ }
4023
+ const fragments = [];
4024
+ messageFormatString.split("").forEach((char, ii) => {
4025
+ if (ii === 0) {
4026
+ state = {
4027
+ [START_INDEX5]: 0,
4028
+ [TYPE5]: messageFormatString[0] === "\\" ? 0 : messageFormatString[0] === "$" ? 2 : 1
4029
+ /* Text */
4030
+ };
4031
+ return;
4032
+ }
4033
+ let nextState;
4034
+ switch (state[TYPE5]) {
4035
+ case 0:
4036
+ nextState = {
4037
+ [START_INDEX5]: ii,
4038
+ [TYPE5]: 1
4039
+ /* Text */
4040
+ };
4041
+ break;
4042
+ case 1:
4043
+ if (char === "\\") {
4044
+ nextState = {
4045
+ [START_INDEX5]: ii,
4046
+ [TYPE5]: 0
4047
+ /* EscapeSequence */
4048
+ };
4049
+ } else if (char === "$") {
4050
+ nextState = {
4051
+ [START_INDEX5]: ii,
4052
+ [TYPE5]: 2
4053
+ /* Variable */
4054
+ };
4055
+ }
4056
+ break;
4057
+ case 2:
4058
+ if (char === "\\") {
4059
+ nextState = {
4060
+ [START_INDEX5]: ii,
4061
+ [TYPE5]: 0
4062
+ /* EscapeSequence */
4063
+ };
4064
+ } else if (char === "$") {
4065
+ nextState = {
4066
+ [START_INDEX5]: ii,
4067
+ [TYPE5]: 2
4068
+ /* Variable */
4069
+ };
4070
+ } else if (!char.match(/\w/)) {
4071
+ nextState = {
4072
+ [START_INDEX5]: ii,
4073
+ [TYPE5]: 1
4074
+ /* Text */
4075
+ };
4076
+ }
4077
+ break;
4078
+ }
4079
+ if (nextState) {
4080
+ if (state !== nextState) {
4081
+ commitStateUpTo(ii);
4082
+ }
4083
+ state = nextState;
4084
+ }
4085
+ });
4086
+ commitStateUpTo();
4087
+ return fragments.join("");
4088
+ }
4089
+ function getErrorMessage5(code, context = {}) {
4090
+ if (process.env.NODE_ENV !== "production") {
4091
+ return getHumanReadableErrorMessage5(code, context);
4092
+ } else {
4093
+ let decodingAdviceMessage = `Solana error #${code}; Decode this error by running \`npx @solana/errors decode -- ${code}`;
4094
+ if (Object.keys(context).length) {
4095
+ decodingAdviceMessage += ` '${encodeContextObject5(context)}'`;
4096
+ }
4097
+ return `${decodingAdviceMessage}\``;
4098
+ }
4099
+ }
4100
+ var SolanaError5 = class extends Error {
4101
+ /**
4102
+ * Indicates the root cause of this {@link SolanaError}, if any.
4103
+ *
4104
+ * For example, a transaction error might have an instruction error as its root cause. In this
4105
+ * case, you will be able to access the instruction error on the transaction error as `cause`.
4106
+ */
4107
+ cause = this.cause;
4108
+ /**
4109
+ * Contains context that can assist in understanding or recovering from a {@link SolanaError}.
4110
+ */
4111
+ context;
4112
+ constructor(...[code, contextAndErrorOptions]) {
4113
+ let context;
4114
+ let errorOptions;
4115
+ if (contextAndErrorOptions) {
4116
+ const { cause, ...contextRest } = contextAndErrorOptions;
4117
+ if (cause) {
4118
+ errorOptions = { cause };
4119
+ }
4120
+ if (Object.keys(contextRest).length > 0) {
4121
+ context = contextRest;
4122
+ }
4123
+ }
4124
+ const message = getErrorMessage5(code, context);
4125
+ super(message, errorOptions);
4126
+ this.context = {
4127
+ __code: code,
4128
+ ...context
4129
+ };
4130
+ this.name = "SolanaError";
4131
+ }
4132
+ };
4133
+
4134
+ // node_modules/@solana/rpc-transport-http/dist/index.node.mjs
4135
+ var DISALLOWED_HEADERS = {
4136
+ accept: true,
4137
+ "content-length": true,
4138
+ "content-type": true
4139
+ };
4140
+ var FORBIDDEN_HEADERS = /* @__PURE__ */ Object.assign(
4141
+ {
4142
+ "accept-charset": true,
4143
+ "access-control-request-headers": true,
4144
+ "access-control-request-method": true,
4145
+ connection: true,
4146
+ "content-length": true,
4147
+ cookie: true,
4148
+ date: true,
4149
+ dnt: true,
4150
+ expect: true,
4151
+ host: true,
4152
+ "keep-alive": true,
4153
+ origin: true,
4154
+ "permissions-policy": true,
4155
+ // Prefix matching is implemented in code, below.
4156
+ // 'proxy-': true,
4157
+ // 'sec-': true,
4158
+ referer: true,
4159
+ te: true,
4160
+ trailer: true,
4161
+ "transfer-encoding": true,
4162
+ upgrade: true,
4163
+ via: true
4164
+ },
4165
+ void 0
4166
+ );
4167
+ function assertIsAllowedHttpRequestHeaders(headers) {
4168
+ const badHeaders = Object.keys(headers).filter((headerName) => {
4169
+ const lowercaseHeaderName = headerName.toLowerCase();
4170
+ return DISALLOWED_HEADERS[headerName.toLowerCase()] === true || FORBIDDEN_HEADERS[headerName.toLowerCase()] === true || lowercaseHeaderName.startsWith("proxy-") || lowercaseHeaderName.startsWith("sec-");
4171
+ });
4172
+ if (badHeaders.length > 0) {
4173
+ throw new SolanaError5(SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN5, {
4174
+ headers: badHeaders
4175
+ });
4176
+ }
4177
+ }
4178
+ function normalizeHeaders(headers) {
4179
+ const out = {};
4180
+ for (const headerName in headers) {
4181
+ out[headerName.toLowerCase()] = headers[headerName];
4182
+ }
4183
+ return out;
4184
+ }
4185
+ function createHttpTransport(config) {
4186
+ if (process.env.NODE_ENV !== "production" && false) ;
4187
+ const { fromJson, headers, toJson, url } = config;
4188
+ if (process.env.NODE_ENV !== "production" && headers) {
4189
+ assertIsAllowedHttpRequestHeaders(headers);
4190
+ }
4191
+ let dispatcherConfig;
4192
+ if ("dispatcher_NODE_ONLY" in config) {
4193
+ dispatcherConfig = { dispatcher: config.dispatcher_NODE_ONLY };
4194
+ }
4195
+ const customHeaders = headers && normalizeHeaders(headers);
4196
+ return async function makeHttpRequest({
4197
+ payload,
4198
+ signal
4199
+ }) {
4200
+ const body = toJson ? toJson(payload) : JSON.stringify(payload);
4201
+ const requestInfo = {
4202
+ ...dispatcherConfig,
4203
+ body,
4204
+ headers: {
4205
+ ...customHeaders,
4206
+ // Keep these headers lowercase so they will override any user-supplied headers above.
4207
+ accept: "application/json",
4208
+ "content-length": body.length.toString(),
4209
+ "content-type": "application/json; charset=utf-8"
4210
+ },
4211
+ method: "POST",
4212
+ signal
4213
+ };
4214
+ const response = await fetch(url, requestInfo);
4215
+ if (!response.ok) {
4216
+ throw new SolanaError5(SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR5, {
4217
+ headers: response.headers,
4218
+ message: response.statusText,
4219
+ statusCode: response.status
4220
+ });
4221
+ }
4222
+ if (fromJson) {
4223
+ return fromJson(await response.text(), payload);
4224
+ }
4225
+ return await response.json();
4226
+ };
4227
+ }
4228
+ var SOLANA_RPC_METHODS = [
4229
+ "getAccountInfo",
4230
+ "getBalance",
4231
+ "getBlock",
4232
+ "getBlockCommitment",
4233
+ "getBlockHeight",
4234
+ "getBlockProduction",
4235
+ "getBlocks",
4236
+ "getBlocksWithLimit",
4237
+ "getBlockTime",
4238
+ "getClusterNodes",
4239
+ "getEpochInfo",
4240
+ "getEpochSchedule",
4241
+ "getFeeForMessage",
4242
+ "getFirstAvailableBlock",
4243
+ "getGenesisHash",
4244
+ "getHealth",
4245
+ "getHighestSnapshotSlot",
4246
+ "getIdentity",
4247
+ "getInflationGovernor",
4248
+ "getInflationRate",
4249
+ "getInflationReward",
4250
+ "getLargestAccounts",
4251
+ "getLatestBlockhash",
4252
+ "getLeaderSchedule",
4253
+ "getMaxRetransmitSlot",
4254
+ "getMaxShredInsertSlot",
4255
+ "getMinimumBalanceForRentExemption",
4256
+ "getMultipleAccounts",
4257
+ "getProgramAccounts",
4258
+ "getRecentPerformanceSamples",
4259
+ "getRecentPrioritizationFees",
4260
+ "getSignaturesForAddress",
4261
+ "getSignatureStatuses",
4262
+ "getSlot",
4263
+ "getSlotLeader",
4264
+ "getSlotLeaders",
4265
+ "getStakeMinimumDelegation",
4266
+ "getSupply",
4267
+ "getTokenAccountBalance",
4268
+ "getTokenAccountsByDelegate",
4269
+ "getTokenAccountsByOwner",
4270
+ "getTokenLargestAccounts",
4271
+ "getTokenSupply",
4272
+ "getTransaction",
4273
+ "getTransactionCount",
4274
+ "getVersion",
4275
+ "getVoteAccounts",
4276
+ "index",
4277
+ "isBlockhashValid",
4278
+ "minimumLedgerSlot",
4279
+ "requestAirdrop",
4280
+ "sendTransaction",
4281
+ "simulateTransaction"
4282
+ ];
4283
+ function isSolanaRequest(payload) {
4284
+ return isJsonRpcPayload(payload) && SOLANA_RPC_METHODS.includes(payload.method);
4285
+ }
4286
+ function createHttpTransportForSolanaRpc(config) {
4287
+ return createHttpTransport({
4288
+ ...config,
4289
+ fromJson: (rawResponse, payload) => isSolanaRequest(payload) ? parseJsonWithBigInts(rawResponse) : JSON.parse(rawResponse),
4290
+ toJson: (payload) => isSolanaRequest(payload) ? stringifyJsonWithBigints(payload) : JSON.stringify(payload)
4291
+ });
4292
+ }
4293
+
4294
+ // node_modules/@solana/rpc/dist/index.node.mjs
4295
+ import { setMaxListeners } from "events";
4296
+
4297
+ // node_modules/@solana/fast-stable-stringify/dist/index.node.mjs
4298
+ var objToString = Object.prototype.toString;
4299
+ var objKeys = Object.keys || function(obj) {
4300
+ const keys = [];
4301
+ for (const name in obj) {
4302
+ keys.push(name);
4303
+ }
4304
+ return keys;
4305
+ };
4306
+ function stringify(val, isArrayProp) {
4307
+ let i, max, str, keys, key, propVal, toStr;
4308
+ if (val === true) {
4309
+ return "true";
4310
+ }
4311
+ if (val === false) {
4312
+ return "false";
4313
+ }
4314
+ switch (typeof val) {
4315
+ case "object":
4316
+ if (val === null) {
4317
+ return null;
4318
+ } else if ("toJSON" in val && typeof val.toJSON === "function") {
4319
+ return stringify(val.toJSON(), isArrayProp);
4320
+ } else {
4321
+ toStr = objToString.call(val);
4322
+ if (toStr === "[object Array]") {
4323
+ str = "[";
4324
+ max = val.length - 1;
4325
+ for (i = 0; i < max; i++) {
4326
+ str += stringify(val[i], true) + ",";
4327
+ }
4328
+ if (max > -1) {
4329
+ str += stringify(val[i], true);
4330
+ }
4331
+ return str + "]";
4332
+ } else if (toStr === "[object Object]") {
4333
+ keys = objKeys(val).sort();
4334
+ max = keys.length;
4335
+ str = "";
4336
+ i = 0;
4337
+ while (i < max) {
4338
+ key = keys[i];
4339
+ propVal = stringify(val[key], false);
4340
+ if (propVal !== void 0) {
4341
+ if (str) {
4342
+ str += ",";
4343
+ }
4344
+ str += JSON.stringify(key) + ":" + propVal;
4345
+ }
4346
+ i++;
4347
+ }
4348
+ return "{" + str + "}";
4349
+ } else {
4350
+ return JSON.stringify(val);
4351
+ }
4352
+ }
4353
+ case "function":
4354
+ case "undefined":
4355
+ return isArrayProp ? null : void 0;
4356
+ case "bigint":
4357
+ return `${val.toString()}n`;
4358
+ case "string":
4359
+ return JSON.stringify(val);
4360
+ default:
4361
+ return isFinite(val) ? val : null;
4362
+ }
4363
+ }
4364
+ function index_default(val) {
4365
+ const returnVal = stringify(val, false);
4366
+ if (returnVal !== void 0) {
4367
+ return "" + returnVal;
4368
+ }
4369
+ }
4370
+
4371
+ // node_modules/@solana/rpc/dist/index.node.mjs
4372
+ function createSolanaJsonRpcIntegerOverflowError(methodName, keyPath, value) {
4373
+ let argumentLabel = "";
4374
+ if (typeof keyPath[0] === "number") {
4375
+ const argPosition = keyPath[0] + 1;
4376
+ const lastDigit = argPosition % 10;
4377
+ const lastTwoDigits = argPosition % 100;
4378
+ if (lastDigit == 1 && lastTwoDigits != 11) {
4379
+ argumentLabel = argPosition + "st";
4380
+ } else if (lastDigit == 2 && lastTwoDigits != 12) {
4381
+ argumentLabel = argPosition + "nd";
4382
+ } else if (lastDigit == 3 && lastTwoDigits != 13) {
4383
+ argumentLabel = argPosition + "rd";
4384
+ } else {
4385
+ argumentLabel = argPosition + "th";
4410
4386
  }
4387
+ } else {
4388
+ argumentLabel = `\`${keyPath[0].toString()}\``;
4411
4389
  }
4412
- const fragments = [];
4413
- messageFormatString.split("").forEach((char, ii) => {
4414
- if (ii === 0) {
4415
- state = {
4416
- [START_INDEX5]: 0,
4417
- [TYPE5]: messageFormatString[0] === "\\" ? 0 : messageFormatString[0] === "$" ? 2 : 1
4418
- /* Text */
4390
+ const path = keyPath.length > 1 ? keyPath.slice(1).map((pathPart) => typeof pathPart === "number" ? `[${pathPart}]` : pathPart).join(".") : void 0;
4391
+ const error = new SolanaError4(SOLANA_ERROR__RPC__INTEGER_OVERFLOW4, {
4392
+ argumentLabel,
4393
+ keyPath,
4394
+ methodName,
4395
+ optionalPathLabel: path ? ` at path \`${path}\`` : "",
4396
+ value,
4397
+ ...path !== void 0 ? { path } : void 0
4398
+ });
4399
+ safeCaptureStackTrace2(error, createSolanaJsonRpcIntegerOverflowError);
4400
+ return error;
4401
+ }
4402
+ var DEFAULT_RPC_CONFIG = {
4403
+ defaultCommitment: "confirmed",
4404
+ onIntegerOverflow(request, keyPath, value) {
4405
+ throw createSolanaJsonRpcIntegerOverflowError(request.methodName, keyPath, value);
4406
+ }
4407
+ };
4408
+ var e2 = class extends globalThis.AbortController {
4409
+ constructor(...t) {
4410
+ super(...t), setMaxListeners(Number.MAX_SAFE_INTEGER, this.signal);
4411
+ }
4412
+ };
4413
+ var EXPLICIT_ABORT_TOKEN;
4414
+ function createExplicitAbortToken() {
4415
+ return process.env.NODE_ENV !== "production" ? {
4416
+ EXPLICIT_ABORT_TOKEN: "This object is thrown from the request that underlies a series of coalesced requests when the last request in that series aborts"
4417
+ } : {};
4418
+ }
4419
+ function getRpcTransportWithRequestCoalescing(transport, getDeduplicationKey) {
4420
+ let coalescedRequestsByDeduplicationKey;
4421
+ return async function makeCoalescedHttpRequest(request) {
4422
+ const { payload, signal } = request;
4423
+ const deduplicationKey = getDeduplicationKey(payload);
4424
+ if (deduplicationKey === void 0) {
4425
+ return await transport(request);
4426
+ }
4427
+ if (!coalescedRequestsByDeduplicationKey) {
4428
+ queueMicrotask(() => {
4429
+ coalescedRequestsByDeduplicationKey = void 0;
4430
+ });
4431
+ coalescedRequestsByDeduplicationKey = {};
4432
+ }
4433
+ if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {
4434
+ const abortController = new e2();
4435
+ const responsePromise = (async () => {
4436
+ try {
4437
+ return await transport({
4438
+ ...request,
4439
+ signal: abortController.signal
4440
+ });
4441
+ } catch (e22) {
4442
+ if (e22 === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {
4443
+ return;
4444
+ }
4445
+ throw e22;
4446
+ }
4447
+ })();
4448
+ coalescedRequestsByDeduplicationKey[deduplicationKey] = {
4449
+ abortController,
4450
+ numConsumers: 0,
4451
+ responsePromise
4419
4452
  };
4420
- return;
4421
4453
  }
4422
- let nextState;
4423
- switch (state[TYPE5]) {
4424
- case 0:
4425
- nextState = {
4426
- [START_INDEX5]: ii,
4427
- [TYPE5]: 1
4428
- /* Text */
4454
+ const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];
4455
+ coalescedRequest.numConsumers++;
4456
+ if (signal) {
4457
+ const responsePromise = coalescedRequest.responsePromise;
4458
+ return await new Promise((resolve, reject) => {
4459
+ const handleAbort = (e22) => {
4460
+ signal.removeEventListener("abort", handleAbort);
4461
+ coalescedRequest.numConsumers -= 1;
4462
+ queueMicrotask(() => {
4463
+ if (coalescedRequest.numConsumers === 0) {
4464
+ const abortController = coalescedRequest.abortController;
4465
+ abortController.abort(EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken());
4466
+ }
4467
+ });
4468
+ reject(e22.target.reason);
4429
4469
  };
4430
- break;
4431
- case 1:
4432
- if (char === "\\") {
4433
- nextState = {
4434
- [START_INDEX5]: ii,
4435
- [TYPE5]: 0
4436
- /* EscapeSequence */
4437
- };
4438
- } else if (char === "$") {
4439
- nextState = {
4440
- [START_INDEX5]: ii,
4441
- [TYPE5]: 2
4442
- /* Variable */
4443
- };
4444
- }
4445
- break;
4446
- case 2:
4447
- if (char === "\\") {
4448
- nextState = {
4449
- [START_INDEX5]: ii,
4450
- [TYPE5]: 0
4451
- /* EscapeSequence */
4452
- };
4453
- } else if (char === "$") {
4454
- nextState = {
4455
- [START_INDEX5]: ii,
4456
- [TYPE5]: 2
4457
- /* Variable */
4458
- };
4459
- } else if (!char.match(/\w/)) {
4460
- nextState = {
4461
- [START_INDEX5]: ii,
4462
- [TYPE5]: 1
4463
- /* Text */
4464
- };
4470
+ signal.addEventListener("abort", handleAbort);
4471
+ responsePromise.then(resolve).catch(reject).finally(() => {
4472
+ signal.removeEventListener("abort", handleAbort);
4473
+ });
4474
+ });
4475
+ } else {
4476
+ return await coalescedRequest.responsePromise;
4477
+ }
4478
+ };
4479
+ }
4480
+ function getSolanaRpcPayloadDeduplicationKey(payload) {
4481
+ return isJsonRpcPayload(payload) ? index_default([payload.method, payload.params]) : void 0;
4482
+ }
4483
+ function normalizeHeaders2(headers) {
4484
+ const out = {};
4485
+ for (const headerName in headers) {
4486
+ out[headerName.toLowerCase()] = headers[headerName];
4487
+ }
4488
+ return out;
4489
+ }
4490
+ function createDefaultRpcTransport(config) {
4491
+ return pipe(
4492
+ createHttpTransportForSolanaRpc({
4493
+ ...config,
4494
+ headers: {
4495
+ ...{
4496
+ // Keep these headers lowercase so they will be overridden by any user-supplied headers below.
4497
+ "accept-encoding": (
4498
+ // Natively supported by Node LTS v20.18.0 and above.
4499
+ "br,gzip,deflate"
4500
+ )
4501
+ // Brotli, gzip, and Deflate, in that order.
4502
+ },
4503
+ ...config.headers ? normalizeHeaders2(config.headers) : void 0,
4504
+ ...{
4505
+ // Keep these headers lowercase so they will override any user-supplied headers above.
4506
+ "solana-client": `js/${"2.3.0"}`
4465
4507
  }
4466
- break;
4467
- }
4468
- if (nextState) {
4469
- if (state !== nextState) {
4470
- commitStateUpTo(ii);
4471
4508
  }
4472
- state = nextState;
4473
- }
4509
+ }),
4510
+ (transport) => getRpcTransportWithRequestCoalescing(transport, getSolanaRpcPayloadDeduplicationKey)
4511
+ );
4512
+ }
4513
+ function createSolanaRpc(clusterUrl, config) {
4514
+ return createSolanaRpcFromTransport(createDefaultRpcTransport({ url: clusterUrl, ...config }));
4515
+ }
4516
+ function createSolanaRpcFromTransport(transport) {
4517
+ return createRpc({
4518
+ api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),
4519
+ transport
4474
4520
  });
4475
- commitStateUpTo();
4476
- return fragments.join("");
4477
4521
  }
4478
- function getErrorMessage5(code, context = {}) {
4479
- if (process.env.NODE_ENV !== "production") {
4480
- return getHumanReadableErrorMessage5(code, context);
4481
- } else {
4482
- let decodingAdviceMessage = `Solana error #${code}; Decode this error by running \`npx @solana/errors decode -- ${code}`;
4483
- if (Object.keys(context).length) {
4484
- decodingAdviceMessage += ` '${encodeContextObject5(context)}'`;
4485
- }
4486
- return `${decodingAdviceMessage}\``;
4522
+
4523
+ // src/instructions/swigBundle.ts
4524
+ import * as bs58Module from "bs58";
4525
+ import { PublicKey as PublicKey4 } from "@solana/web3.js";
4526
+ var bs58 = bs58Module.default ?? bs58Module;
4527
+ var SWIG_ID_DOMAIN = "dexter-swig-id:v1:";
4528
+ var DEFAULT_SESSION_TTL_SECONDS = BigInt(30 * 24 * 60 * 60);
4529
+ var DEFAULT_SPEND_LIMIT_ATOMIC = BigInt(1e9);
4530
+ var SWIG_PROGRAM_EXEC_PREFIX = new Uint8Array([
4531
+ 178,
4532
+ 87,
4533
+ 206,
4534
+ 68,
4535
+ 201,
4536
+ 186,
4537
+ 164,
4538
+ 232
4539
+ ]);
4540
+ var SWIG_PROGRAM_EXEC_PREFIX_SETTLE_TAB = new Uint8Array([
4541
+ 173,
4542
+ 22,
4543
+ 98,
4544
+ 31,
4545
+ 110,
4546
+ 129,
4547
+ 59,
4548
+ 161
4549
+ ]);
4550
+ var SWIG_PROGRAM_EXEC_MARKERS = [
4551
+ SWIG_PROGRAM_EXEC_PREFIX,
4552
+ SWIG_PROGRAM_EXEC_PREFIX_SETTLE_TAB
4553
+ ];
4554
+ function deriveSwigId(identitySeed, hmacKey) {
4555
+ if (hmacKey.length !== 32) {
4556
+ throw new Error(`hmacKey must be 32 bytes, got ${hmacKey.length}`);
4487
4557
  }
4558
+ return createHmac("sha256", Buffer.from(hmacKey)).update(SWIG_ID_DOMAIN).update(Buffer.from(identitySeed)).digest();
4488
4559
  }
4489
- var SolanaError5 = class extends Error {
4490
- /**
4491
- * Indicates the root cause of this {@link SolanaError}, if any.
4492
- *
4493
- * For example, a transaction error might have an instruction error as its root cause. In this
4494
- * case, you will be able to access the instruction error on the transaction error as `cause`.
4495
- */
4496
- cause = this.cause;
4497
- /**
4498
- * Contains context that can assist in understanding or recovering from a {@link SolanaError}.
4499
- */
4500
- context;
4501
- constructor(...[code, contextAndErrorOptions]) {
4502
- let context;
4503
- let errorOptions;
4504
- if (contextAndErrorOptions) {
4505
- const { cause, ...contextRest } = contextAndErrorOptions;
4506
- if (cause) {
4507
- errorOptions = { cause };
4508
- }
4509
- if (Object.keys(contextRest).length > 0) {
4510
- context = contextRest;
4560
+ async function buildSwigCreationBundle(params) {
4561
+ const {
4562
+ feePayer,
4563
+ dexterMasterPubkey,
4564
+ identitySeed,
4565
+ hmacKey,
4566
+ sessionTtlSeconds = DEFAULT_SESSION_TTL_SECONDS,
4567
+ spendLimitAtomic = DEFAULT_SPEND_LIMIT_ATOMIC
4568
+ } = params;
4569
+ const swigId = deriveSwigId(identitySeed, hmacKey);
4570
+ const swigPda = await findSwigPda(swigId);
4571
+ const swigAddressStr = String(swigPda);
4572
+ const feePayerBytes = bs58.decode(feePayer);
4573
+ const vaultProgramIdBytes = Uint8Array.from(DEXTER_VAULT_PROGRAM_ID.toBytes());
4574
+ const dexterPubkeyBytes = bs58.decode(dexterMasterPubkey);
4575
+ const bootstrapAuthorityInfo = createEd25519AuthorityInfo(feePayerBytes);
4576
+ const bootstrapActions = Actions.set().manageAuthority().get();
4577
+ const vaultAuthorityInfo = createProgramExecAuthorityInfo(
4578
+ vaultProgramIdBytes,
4579
+ SWIG_PROGRAM_EXEC_PREFIX
4580
+ );
4581
+ const vaultActions = Actions.set().all().get();
4582
+ const vaultTabSettleAuthorityInfo = createProgramExecAuthorityInfo(
4583
+ vaultProgramIdBytes,
4584
+ SWIG_PROGRAM_EXEC_PREFIX_SETTLE_TAB
4585
+ );
4586
+ const vaultTabSettleActions = Actions.set().all().get();
4587
+ const sessionAuthorityInfo = createEd25519SessionAuthorityInfo(
4588
+ dexterPubkeyBytes,
4589
+ sessionTtlSeconds
4590
+ );
4591
+ const sessionActions = Actions.set().tokenLimit({ mint: bs58.decode(USDC_MAINNET), amount: spendLimitAtomic }).programAll().get();
4592
+ const builder = getCreateSwigWithMultipleAuthoritiesInstructionContextBuilder({
4593
+ payer: address(feePayer),
4594
+ swigAddress: address(swigAddressStr),
4595
+ id: swigId,
4596
+ actions: bootstrapActions,
4597
+ authorityInfo: bootstrapAuthorityInfo,
4598
+ options: {}
4599
+ }).addAuthority(vaultAuthorityInfo, vaultActions).addAuthority(sessionAuthorityInfo, sessionActions).addAuthority(vaultTabSettleAuthorityInfo, vaultTabSettleActions);
4600
+ const contexts = await builder.getInstructionContexts();
4601
+ const instructions = contexts.flatMap((ctx) => getInstructionsFromContext(ctx));
4602
+ return {
4603
+ swigAddress: swigAddressStr,
4604
+ swigIdBase58: bs58.encode(swigId),
4605
+ instructions
4606
+ };
4607
+ }
4608
+ async function expectedSwigAddressFor(identitySeed, hmacKey) {
4609
+ const swigId = deriveSwigId(identitySeed, hmacKey);
4610
+ return String(await findSwigPda(swigId));
4611
+ }
4612
+ async function verifySwigIsOurs(params) {
4613
+ const { swigAddress, identitySeed, hmacKey, dexterMasterPubkey, rpcEndpoint } = params;
4614
+ const expected = await expectedSwigAddressFor(identitySeed, hmacKey);
4615
+ if (swigAddress !== expected) {
4616
+ return {
4617
+ ok: false,
4618
+ reason: `swig_address_mismatch: expected ${expected}, got ${swigAddress}`
4619
+ };
4620
+ }
4621
+ try {
4622
+ const rpc = createSolanaRpc(rpcEndpoint);
4623
+ const swig = await fetchNullableSwig(rpc, address(swigAddress));
4624
+ if (swig) {
4625
+ const ourRoles = swig.findRolesByAuthorityAddress(bs58.decode(dexterMasterPubkey));
4626
+ if (!ourRoles || ourRoles.length === 0) {
4627
+ return {
4628
+ ok: false,
4629
+ reason: "swig_missing_session_master_role"
4630
+ };
4511
4631
  }
4512
4632
  }
4513
- const message = getErrorMessage5(code, context);
4514
- super(message, errorOptions);
4515
- this.context = {
4516
- __code: code,
4517
- ...context
4518
- };
4519
- this.name = "SolanaError";
4633
+ } catch {
4520
4634
  }
4521
- };
4635
+ return { ok: true };
4636
+ }
4637
+ function deriveVaultPda(supabaseUserId) {
4638
+ if (supabaseUserId.length !== 16) {
4639
+ throw new Error("supabaseUserId must be 16 bytes (UUID v4)");
4640
+ }
4641
+ const [pda, bump] = PublicKey4.findProgramAddressSync(
4642
+ [Buffer.from("vault"), Buffer.from(supabaseUserId)],
4643
+ DEXTER_VAULT_PROGRAM_ID
4644
+ );
4645
+ return { pda, bump };
4646
+ }
4522
4647
 
4523
- // node_modules/@solana/rpc-transport-http/dist/index.node.mjs
4524
- var DISALLOWED_HEADERS = {
4525
- accept: true,
4526
- "content-length": true,
4527
- "content-type": true
4528
- };
4529
- var FORBIDDEN_HEADERS = /* @__PURE__ */ Object.assign(
4530
- {
4531
- "accept-charset": true,
4532
- "access-control-request-headers": true,
4533
- "access-control-request-method": true,
4534
- connection: true,
4535
- "content-length": true,
4536
- cookie: true,
4537
- date: true,
4538
- dnt: true,
4539
- expect: true,
4540
- host: true,
4541
- "keep-alive": true,
4542
- origin: true,
4543
- "permissions-policy": true,
4544
- // Prefix matching is implemented in code, below.
4545
- // 'proxy-': true,
4546
- // 'sec-': true,
4547
- referer: true,
4548
- te: true,
4549
- trailer: true,
4550
- "transfer-encoding": true,
4551
- upgrade: true,
4552
- via: true
4553
- },
4554
- void 0
4555
- );
4556
- function assertIsAllowedHttpRequestHeaders(headers) {
4557
- const badHeaders = Object.keys(headers).filter((headerName) => {
4558
- const lowercaseHeaderName = headerName.toLowerCase();
4559
- return DISALLOWED_HEADERS[headerName.toLowerCase()] === true || FORBIDDEN_HEADERS[headerName.toLowerCase()] === true || lowercaseHeaderName.startsWith("proxy-") || lowercaseHeaderName.startsWith("sec-");
4648
+ // src/instructions/setSwigAtomic.ts
4649
+ var SET_SWIG_ATOMIC_DISCRIMINATOR = new Uint8Array([
4650
+ 119,
4651
+ 111,
4652
+ 247,
4653
+ 215,
4654
+ 190,
4655
+ 3,
4656
+ 170,
4657
+ 23
4658
+ ]);
4659
+ function buildSetSwigAtomicInstruction(params) {
4660
+ if (params.swigId.length !== 32) {
4661
+ throw new Error(`swigId must be 32 bytes, got ${params.swigId.length}`);
4662
+ }
4663
+ if (params.authenticatorData.length < 37) {
4664
+ throw new Error(`authenticatorData must be at least 37 bytes`);
4665
+ }
4666
+ const cdj = params.clientDataJSON;
4667
+ const ad = params.authenticatorData;
4668
+ const dataLen = 8 + // discriminator
4669
+ 32 + // swig_id
4670
+ 1 + // swig_account_bump
4671
+ 1 + // swig_wallet_address_bump
4672
+ 32 + // dexter_master_pubkey
4673
+ 4 + cdj.length + // client_data_json (len-prefixed)
4674
+ 4 + ad.length;
4675
+ const data = new Uint8Array(dataLen);
4676
+ const view = new DataView(data.buffer);
4677
+ let off = 0;
4678
+ data.set(SET_SWIG_ATOMIC_DISCRIMINATOR, off);
4679
+ off += 8;
4680
+ data.set(params.swigId, off);
4681
+ off += 32;
4682
+ data[off++] = params.swigAccountBump;
4683
+ data[off++] = params.swigWalletAddressBump;
4684
+ data.set(params.dexterMasterPubkey.toBytes(), off);
4685
+ off += 32;
4686
+ view.setUint32(off, cdj.length, true);
4687
+ off += 4;
4688
+ data.set(cdj, off);
4689
+ off += cdj.length;
4690
+ view.setUint32(off, ad.length, true);
4691
+ off += 4;
4692
+ data.set(ad, off);
4693
+ off += ad.length;
4694
+ if (off !== dataLen) throw new Error(`internal: byte offset mismatch (${off} vs ${dataLen})`);
4695
+ return new TransactionInstruction3({
4696
+ programId: DEXTER_VAULT_PROGRAM_ID,
4697
+ keys: [
4698
+ { pubkey: params.vaultPda, isSigner: false, isWritable: true },
4699
+ { pubkey: params.feePayer, isSigner: true, isWritable: true },
4700
+ { pubkey: params.swigAddress, isSigner: false, isWritable: true },
4701
+ { pubkey: params.swigWalletAddress, isSigner: false, isWritable: true },
4702
+ { pubkey: SWIG_PROGRAM_ID, isSigner: false, isWritable: false },
4703
+ { pubkey: SystemProgram2.programId, isSigner: false, isWritable: false },
4704
+ { pubkey: SYSVAR_INSTRUCTIONS_PUBKEY2, isSigner: false, isWritable: false }
4705
+ ],
4706
+ data: Buffer.from(data)
4560
4707
  });
4561
- if (badHeaders.length > 0) {
4562
- throw new SolanaError5(SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN5, {
4563
- headers: badHeaders
4564
- });
4565
- }
4566
4708
  }
4567
- function normalizeHeaders(headers) {
4568
- const out = {};
4569
- for (const headerName in headers) {
4570
- out[headerName.toLowerCase()] = headers[headerName];
4571
- }
4572
- return out;
4709
+ function buildSetSwigAtomicFromIdentity(params) {
4710
+ const swigId = Uint8Array.from(
4711
+ deriveSwigId(params.identitySeed, params.hmacKey)
4712
+ );
4713
+ const [swigAddress, swigAccountBump] = PublicKey5.findProgramAddressSync(
4714
+ [Buffer.from(swigId)],
4715
+ SWIG_PROGRAM_ID
4716
+ );
4717
+ const [swigWalletAddress, swigWalletAddressBump] = PublicKey5.findProgramAddressSync(
4718
+ [swigAddress.toBytes()],
4719
+ SWIG_PROGRAM_ID
4720
+ );
4721
+ return buildSetSwigAtomicInstruction({
4722
+ vaultPda: params.vaultPda,
4723
+ swigAddress,
4724
+ swigWalletAddress,
4725
+ feePayer: params.feePayer,
4726
+ dexterMasterPubkey: params.dexterMasterPubkey,
4727
+ swigId,
4728
+ swigAccountBump,
4729
+ swigWalletAddressBump,
4730
+ clientDataJSON: params.clientDataJSON,
4731
+ authenticatorData: params.authenticatorData
4732
+ });
4573
4733
  }
4574
- function createHttpTransport(config) {
4575
- if (process.env.NODE_ENV !== "production" && false) ;
4576
- const { fromJson, headers, toJson, url } = config;
4577
- if (process.env.NODE_ENV !== "production" && headers) {
4578
- assertIsAllowedHttpRequestHeaders(headers);
4579
- }
4580
- let dispatcherConfig;
4581
- if ("dispatcher_NODE_ONLY" in config) {
4582
- dispatcherConfig = { dispatcher: config.dispatcher_NODE_ONLY };
4583
- }
4584
- const customHeaders = headers && normalizeHeaders(headers);
4585
- return async function makeHttpRequest({
4586
- payload,
4587
- signal
4588
- }) {
4589
- const body = toJson ? toJson(payload) : JSON.stringify(payload);
4590
- const requestInfo = {
4591
- ...dispatcherConfig,
4592
- body,
4593
- headers: {
4594
- ...customHeaders,
4595
- // Keep these headers lowercase so they will override any user-supplied headers above.
4596
- accept: "application/json",
4597
- "content-length": body.length.toString(),
4598
- "content-type": "application/json; charset=utf-8"
4599
- },
4600
- method: "POST",
4601
- signal
4602
- };
4603
- const response = await fetch(url, requestInfo);
4604
- if (!response.ok) {
4605
- throw new SolanaError5(SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR5, {
4606
- headers: response.headers,
4607
- message: response.statusText,
4608
- statusCode: response.status
4609
- });
4610
- }
4611
- if (fromJson) {
4612
- return fromJson(await response.text(), payload);
4613
- }
4614
- return await response.json();
4615
- };
4734
+
4735
+ // src/instructions/registerSession.ts
4736
+ import { TransactionInstruction as TransactionInstruction4 } from "@solana/web3.js";
4737
+ function encodeU64LE(value) {
4738
+ const buf = new Uint8Array(8);
4739
+ new DataView(buf.buffer).setBigUint64(0, value, true);
4740
+ return buf;
4616
4741
  }
4617
- var SOLANA_RPC_METHODS = [
4618
- "getAccountInfo",
4619
- "getBalance",
4620
- "getBlock",
4621
- "getBlockCommitment",
4622
- "getBlockHeight",
4623
- "getBlockProduction",
4624
- "getBlocks",
4625
- "getBlocksWithLimit",
4626
- "getBlockTime",
4627
- "getClusterNodes",
4628
- "getEpochInfo",
4629
- "getEpochSchedule",
4630
- "getFeeForMessage",
4631
- "getFirstAvailableBlock",
4632
- "getGenesisHash",
4633
- "getHealth",
4634
- "getHighestSnapshotSlot",
4635
- "getIdentity",
4636
- "getInflationGovernor",
4637
- "getInflationRate",
4638
- "getInflationReward",
4639
- "getLargestAccounts",
4640
- "getLatestBlockhash",
4641
- "getLeaderSchedule",
4642
- "getMaxRetransmitSlot",
4643
- "getMaxShredInsertSlot",
4644
- "getMinimumBalanceForRentExemption",
4645
- "getMultipleAccounts",
4646
- "getProgramAccounts",
4647
- "getRecentPerformanceSamples",
4648
- "getRecentPrioritizationFees",
4649
- "getSignaturesForAddress",
4650
- "getSignatureStatuses",
4651
- "getSlot",
4652
- "getSlotLeader",
4653
- "getSlotLeaders",
4654
- "getStakeMinimumDelegation",
4655
- "getSupply",
4656
- "getTokenAccountBalance",
4657
- "getTokenAccountsByDelegate",
4658
- "getTokenAccountsByOwner",
4659
- "getTokenLargestAccounts",
4660
- "getTokenSupply",
4661
- "getTransaction",
4662
- "getTransactionCount",
4663
- "getVersion",
4664
- "getVoteAccounts",
4665
- "index",
4666
- "isBlockhashValid",
4667
- "minimumLedgerSlot",
4668
- "requestAirdrop",
4669
- "sendTransaction",
4670
- "simulateTransaction"
4671
- ];
4672
- function isSolanaRequest(payload) {
4673
- return isJsonRpcPayload(payload) && SOLANA_RPC_METHODS.includes(payload.method);
4742
+ function encodeI64LE(value) {
4743
+ const buf = new Uint8Array(8);
4744
+ new DataView(buf.buffer).setBigInt64(0, value, true);
4745
+ return buf;
4674
4746
  }
4675
- function createHttpTransportForSolanaRpc(config) {
4676
- return createHttpTransport({
4677
- ...config,
4678
- fromJson: (rawResponse, payload) => isSolanaRequest(payload) ? parseJsonWithBigInts(rawResponse) : JSON.parse(rawResponse),
4679
- toJson: (payload) => isSolanaRequest(payload) ? stringifyJsonWithBigints(payload) : JSON.stringify(payload)
4680
- });
4747
+ function encodeU32LE(value) {
4748
+ const buf = new Uint8Array(4);
4749
+ new DataView(buf.buffer).setUint32(0, value >>> 0, true);
4750
+ return buf;
4681
4751
  }
4682
-
4683
- // node_modules/@solana/rpc/dist/index.node.mjs
4684
- import { setMaxListeners } from "events";
4685
-
4686
- // node_modules/@solana/fast-stable-stringify/dist/index.node.mjs
4687
- var objToString = Object.prototype.toString;
4688
- var objKeys = Object.keys || function(obj) {
4689
- const keys = [];
4690
- for (const name in obj) {
4691
- keys.push(name);
4692
- }
4693
- return keys;
4694
- };
4695
- function stringify(val, isArrayProp) {
4696
- let i, max, str, keys, key, propVal, toStr;
4697
- if (val === true) {
4698
- return "true";
4699
- }
4700
- if (val === false) {
4701
- return "false";
4752
+ function encodeVecU8(bytes) {
4753
+ const out = new Uint8Array(4 + bytes.length);
4754
+ new DataView(out.buffer).setUint32(0, bytes.length >>> 0, true);
4755
+ out.set(bytes, 4);
4756
+ return out;
4757
+ }
4758
+ function concatBytes(...parts) {
4759
+ const total = parts.reduce((n, p) => n + p.length, 0);
4760
+ const out = new Uint8Array(total);
4761
+ let o2 = 0;
4762
+ for (const p of parts) {
4763
+ out.set(p, o2);
4764
+ o2 += p.length;
4702
4765
  }
4703
- switch (typeof val) {
4704
- case "object":
4705
- if (val === null) {
4706
- return null;
4707
- } else if ("toJSON" in val && typeof val.toJSON === "function") {
4708
- return stringify(val.toJSON(), isArrayProp);
4709
- } else {
4710
- toStr = objToString.call(val);
4711
- if (toStr === "[object Array]") {
4712
- str = "[";
4713
- max = val.length - 1;
4714
- for (i = 0; i < max; i++) {
4715
- str += stringify(val[i], true) + ",";
4716
- }
4717
- if (max > -1) {
4718
- str += stringify(val[i], true);
4719
- }
4720
- return str + "]";
4721
- } else if (toStr === "[object Object]") {
4722
- keys = objKeys(val).sort();
4723
- max = keys.length;
4724
- str = "";
4725
- i = 0;
4726
- while (i < max) {
4727
- key = keys[i];
4728
- propVal = stringify(val[key], false);
4729
- if (propVal !== void 0) {
4730
- if (str) {
4731
- str += ",";
4732
- }
4733
- str += JSON.stringify(key) + ":" + propVal;
4734
- }
4735
- i++;
4736
- }
4737
- return "{" + str + "}";
4738
- } else {
4739
- return JSON.stringify(val);
4740
- }
4741
- }
4742
- case "function":
4743
- case "undefined":
4744
- return isArrayProp ? null : void 0;
4745
- case "bigint":
4746
- return `${val.toString()}n`;
4747
- case "string":
4748
- return JSON.stringify(val);
4749
- default:
4750
- return isFinite(val) ? val : null;
4766
+ return out;
4767
+ }
4768
+ function buildRegisterSessionKeyInstruction(args) {
4769
+ if (args.sessionPubkey.length !== 32) {
4770
+ throw new Error(`sessionPubkey must be 32 bytes, got ${args.sessionPubkey.length}`);
4751
4771
  }
4772
+ const data = concatBytes(
4773
+ DISCRIMINATORS.register_session_key,
4774
+ args.sessionPubkey,
4775
+ encodeU64LE(args.maxAmount),
4776
+ encodeI64LE(args.expiresAt),
4777
+ args.allowedCounterparty.toBytes(),
4778
+ encodeU32LE(args.nonce),
4779
+ encodeVecU8(args.clientDataJSON),
4780
+ encodeVecU8(args.authenticatorData)
4781
+ );
4782
+ return new TransactionInstruction4({
4783
+ keys: [
4784
+ { pubkey: args.vaultPda, isSigner: false, isWritable: true },
4785
+ { pubkey: INSTRUCTIONS_SYSVAR_ID, isSigner: false, isWritable: false }
4786
+ ],
4787
+ programId: DEXTER_VAULT_PROGRAM_ID,
4788
+ data: Buffer.from(data)
4789
+ });
4752
4790
  }
4753
- function index_default(val) {
4754
- const returnVal = stringify(val, false);
4755
- if (returnVal !== void 0) {
4756
- return "" + returnVal;
4791
+
4792
+ // src/instructions/revokeSession.ts
4793
+ import { TransactionInstruction as TransactionInstruction5 } from "@solana/web3.js";
4794
+ function encodeVecU82(bytes) {
4795
+ const out = new Uint8Array(4 + bytes.length);
4796
+ new DataView(out.buffer).setUint32(0, bytes.length >>> 0, true);
4797
+ out.set(bytes, 4);
4798
+ return out;
4799
+ }
4800
+ function concatBytes2(...parts) {
4801
+ const total = parts.reduce((n, p) => n + p.length, 0);
4802
+ const out = new Uint8Array(total);
4803
+ let o2 = 0;
4804
+ for (const p of parts) {
4805
+ out.set(p, o2);
4806
+ o2 += p.length;
4757
4807
  }
4808
+ return out;
4809
+ }
4810
+ function buildRevokeSessionKeyInstruction(args) {
4811
+ const data = concatBytes2(
4812
+ DISCRIMINATORS.revoke_session_key,
4813
+ encodeVecU82(args.clientDataJSON),
4814
+ encodeVecU82(args.authenticatorData)
4815
+ );
4816
+ return new TransactionInstruction5({
4817
+ keys: [
4818
+ { pubkey: args.vaultPda, isSigner: false, isWritable: true },
4819
+ { pubkey: INSTRUCTIONS_SYSVAR_ID, isSigner: false, isWritable: false }
4820
+ ],
4821
+ programId: DEXTER_VAULT_PROGRAM_ID,
4822
+ data: Buffer.from(data)
4823
+ });
4758
4824
  }
4759
4825
 
4760
- // node_modules/@solana/rpc/dist/index.node.mjs
4761
- function createSolanaJsonRpcIntegerOverflowError(methodName, keyPath, value) {
4762
- let argumentLabel = "";
4763
- if (typeof keyPath[0] === "number") {
4764
- const argPosition = keyPath[0] + 1;
4765
- const lastDigit = argPosition % 10;
4766
- const lastTwoDigits = argPosition % 100;
4767
- if (lastDigit == 1 && lastTwoDigits != 11) {
4768
- argumentLabel = argPosition + "st";
4769
- } else if (lastDigit == 2 && lastTwoDigits != 12) {
4770
- argumentLabel = argPosition + "nd";
4771
- } else if (lastDigit == 3 && lastTwoDigits != 13) {
4772
- argumentLabel = argPosition + "rd";
4773
- } else {
4774
- argumentLabel = argPosition + "th";
4775
- }
4776
- } else {
4777
- argumentLabel = `\`${keyPath[0].toString()}\``;
4778
- }
4779
- const path = keyPath.length > 1 ? keyPath.slice(1).map((pathPart) => typeof pathPart === "number" ? `[${pathPart}]` : pathPart).join(".") : void 0;
4780
- const error = new SolanaError4(SOLANA_ERROR__RPC__INTEGER_OVERFLOW4, {
4781
- argumentLabel,
4782
- keyPath,
4783
- methodName,
4784
- optionalPathLabel: path ? ` at path \`${path}\`` : "",
4785
- value,
4786
- ...path !== void 0 ? { path } : void 0
4826
+ // src/instructions/settleVoucher.ts
4827
+ import { TransactionInstruction as TransactionInstruction6 } from "@solana/web3.js";
4828
+ function encodeU64(value) {
4829
+ const out = Buffer.alloc(8);
4830
+ out.writeBigUInt64LE(value, 0);
4831
+ return out;
4832
+ }
4833
+ function encodeBool(value) {
4834
+ return Buffer.from([value ? 1 : 0]);
4835
+ }
4836
+ function buildSettleVoucherInstruction(p) {
4837
+ const argsBuf = Buffer.concat([encodeU64(p.amount), encodeBool(p.increment)]);
4838
+ const data = Buffer.concat([Buffer.from(DISCRIMINATORS.settle_voucher), argsBuf]);
4839
+ return new TransactionInstruction6({
4840
+ programId: DEXTER_VAULT_PROGRAM_ID,
4841
+ keys: [
4842
+ { pubkey: p.vaultPda, isSigner: false, isWritable: true },
4843
+ { pubkey: p.dexterAuthority, isSigner: true, isWritable: false }
4844
+ ],
4845
+ data
4787
4846
  });
4788
- safeCaptureStackTrace2(error, createSolanaJsonRpcIntegerOverflowError);
4789
- return error;
4790
4847
  }
4791
- var DEFAULT_RPC_CONFIG = {
4792
- defaultCommitment: "confirmed",
4793
- onIntegerOverflow(request, keyPath, value) {
4794
- throw createSolanaJsonRpcIntegerOverflowError(request.methodName, keyPath, value);
4795
- }
4796
- };
4797
- var e2 = class extends globalThis.AbortController {
4798
- constructor(...t) {
4799
- super(...t), setMaxListeners(Number.MAX_SAFE_INTEGER, this.signal);
4800
- }
4801
- };
4802
- var EXPLICIT_ABORT_TOKEN;
4803
- function createExplicitAbortToken() {
4804
- return process.env.NODE_ENV !== "production" ? {
4805
- EXPLICIT_ABORT_TOKEN: "This object is thrown from the request that underlies a series of coalesced requests when the last request in that series aborts"
4806
- } : {};
4848
+
4849
+ // src/instructions/settleTabVoucher.ts
4850
+ import {
4851
+ TransactionInstruction as TransactionInstruction8,
4852
+ SYSVAR_INSTRUCTIONS_PUBKEY as SYSVAR_INSTRUCTIONS_PUBKEY4
4853
+ } from "@solana/web3.js";
4854
+
4855
+ // src/instructions/withdraw.ts
4856
+ import {
4857
+ PublicKey as PublicKey9,
4858
+ TransactionInstruction as TransactionInstruction7,
4859
+ SYSVAR_INSTRUCTIONS_PUBKEY as SYSVAR_INSTRUCTIONS_PUBKEY3
4860
+ } from "@solana/web3.js";
4861
+ function encodeBytesVec2(buf) {
4862
+ const out = Buffer.alloc(4 + buf.length);
4863
+ out.writeUInt32LE(buf.length, 0);
4864
+ Buffer.from(buf).copy(out, 4);
4865
+ return out;
4807
4866
  }
4808
- function getRpcTransportWithRequestCoalescing(transport, getDeduplicationKey) {
4809
- let coalescedRequestsByDeduplicationKey;
4810
- return async function makeCoalescedHttpRequest(request) {
4811
- const { payload, signal } = request;
4812
- const deduplicationKey = getDeduplicationKey(payload);
4813
- if (deduplicationKey === void 0) {
4814
- return await transport(request);
4815
- }
4816
- if (!coalescedRequestsByDeduplicationKey) {
4817
- queueMicrotask(() => {
4818
- coalescedRequestsByDeduplicationKey = void 0;
4819
- });
4820
- coalescedRequestsByDeduplicationKey = {};
4821
- }
4822
- if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {
4823
- const abortController = new e2();
4824
- const responsePromise = (async () => {
4825
- try {
4826
- return await transport({
4827
- ...request,
4828
- signal: abortController.signal
4829
- });
4830
- } catch (e22) {
4831
- if (e22 === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {
4832
- return;
4833
- }
4834
- throw e22;
4835
- }
4836
- })();
4837
- coalescedRequestsByDeduplicationKey[deduplicationKey] = {
4838
- abortController,
4839
- numConsumers: 0,
4840
- responsePromise
4841
- };
4842
- }
4843
- const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];
4844
- coalescedRequest.numConsumers++;
4845
- if (signal) {
4846
- const responsePromise = coalescedRequest.responsePromise;
4847
- return await new Promise((resolve, reject) => {
4848
- const handleAbort = (e22) => {
4849
- signal.removeEventListener("abort", handleAbort);
4850
- coalescedRequest.numConsumers -= 1;
4851
- queueMicrotask(() => {
4852
- if (coalescedRequest.numConsumers === 0) {
4853
- const abortController = coalescedRequest.abortController;
4854
- abortController.abort(EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken());
4855
- }
4856
- });
4857
- reject(e22.target.reason);
4858
- };
4859
- signal.addEventListener("abort", handleAbort);
4860
- responsePromise.then(resolve).catch(reject).finally(() => {
4861
- signal.removeEventListener("abort", handleAbort);
4862
- });
4863
- });
4864
- } else {
4865
- return await coalescedRequest.responsePromise;
4866
- }
4867
- };
4867
+ function encodeU642(value) {
4868
+ const out = Buffer.alloc(8);
4869
+ out.writeBigUInt64LE(value, 0);
4870
+ return out;
4868
4871
  }
4869
- function getSolanaRpcPayloadDeduplicationKey(payload) {
4870
- return isJsonRpcPayload(payload) ? index_default([payload.method, payload.params]) : void 0;
4872
+ function encodeI64(value) {
4873
+ const out = Buffer.alloc(8);
4874
+ out.writeBigInt64LE(value, 0);
4875
+ return out;
4871
4876
  }
4872
- function normalizeHeaders2(headers) {
4873
- const out = {};
4874
- for (const headerName in headers) {
4875
- out[headerName.toLowerCase()] = headers[headerName];
4877
+ function encodePubkey2(key) {
4878
+ return Buffer.from(key.toBytes());
4879
+ }
4880
+ function deriveSwigWalletAddress(swigAddress) {
4881
+ const [pda] = PublicKey9.findProgramAddressSync(
4882
+ [Buffer.from("swig-wallet-address"), swigAddress.toBuffer()],
4883
+ SWIG_PROGRAM_ID
4884
+ );
4885
+ return pda;
4886
+ }
4887
+ function buildRequestWithdrawalInstruction(p) {
4888
+ const argsBuf = Buffer.concat([
4889
+ encodeU642(p.amount),
4890
+ encodePubkey2(p.destination),
4891
+ encodeI64(p.signedAt),
4892
+ encodeBytesVec2(p.clientDataJSON),
4893
+ encodeBytesVec2(p.authenticatorData)
4894
+ ]);
4895
+ const data = Buffer.concat([Buffer.from(DISCRIMINATORS.request_withdrawal), argsBuf]);
4896
+ return new TransactionInstruction7({
4897
+ programId: DEXTER_VAULT_PROGRAM_ID,
4898
+ keys: [
4899
+ { pubkey: p.vaultPda, isSigner: false, isWritable: true },
4900
+ { pubkey: SYSVAR_INSTRUCTIONS_PUBKEY3, isSigner: false, isWritable: false }
4901
+ ],
4902
+ data
4903
+ });
4904
+ }
4905
+ function buildFinalizeWithdrawalInstruction(p) {
4906
+ const argsBuf = Buffer.concat([
4907
+ encodeBytesVec2(p.clientDataJSON),
4908
+ encodeBytesVec2(p.authenticatorData)
4909
+ ]);
4910
+ const data = Buffer.concat([Buffer.from(DISCRIMINATORS.finalize_withdrawal), argsBuf]);
4911
+ const swigWalletAddress = deriveSwigWalletAddress(p.swigAddress);
4912
+ return new TransactionInstruction7({
4913
+ programId: DEXTER_VAULT_PROGRAM_ID,
4914
+ keys: [
4915
+ { pubkey: p.swigAddress, isSigner: false, isWritable: false },
4916
+ { pubkey: swigWalletAddress, isSigner: false, isWritable: false },
4917
+ { pubkey: p.vaultPda, isSigner: false, isWritable: true },
4918
+ { pubkey: SYSVAR_INSTRUCTIONS_PUBKEY3, isSigner: false, isWritable: false }
4919
+ ],
4920
+ data
4921
+ });
4922
+ }
4923
+ function buildForceReleaseInstruction(p) {
4924
+ const argsBuf = Buffer.concat([
4925
+ encodeBytesVec2(p.clientDataJSON),
4926
+ encodeBytesVec2(p.authenticatorData)
4927
+ ]);
4928
+ const data = Buffer.concat([Buffer.from(DISCRIMINATORS.force_release), argsBuf]);
4929
+ return new TransactionInstruction7({
4930
+ programId: DEXTER_VAULT_PROGRAM_ID,
4931
+ keys: [
4932
+ { pubkey: p.vaultPda, isSigner: false, isWritable: true },
4933
+ { pubkey: SYSVAR_INSTRUCTIONS_PUBKEY3, isSigner: false, isWritable: false }
4934
+ ],
4935
+ data
4936
+ });
4937
+ }
4938
+
4939
+ // src/instructions/settleTabVoucher.ts
4940
+ function encodeFixedBytes2(buf, len) {
4941
+ if (buf.length !== len) {
4942
+ throw new Error(`expected ${len} bytes, got ${buf.length}`);
4876
4943
  }
4877
- return out;
4944
+ return Buffer.from(buf);
4878
4945
  }
4879
- function createDefaultRpcTransport(config) {
4880
- return pipe(
4881
- createHttpTransportForSolanaRpc({
4882
- ...config,
4883
- headers: {
4884
- ...{
4885
- // Keep these headers lowercase so they will be overridden by any user-supplied headers below.
4886
- "accept-encoding": (
4887
- // Natively supported by Node LTS v20.18.0 and above.
4888
- "br,gzip,deflate"
4889
- )
4890
- // Brotli, gzip, and Deflate, in that order.
4891
- },
4892
- ...config.headers ? normalizeHeaders2(config.headers) : void 0,
4893
- ...{
4894
- // Keep these headers lowercase so they will override any user-supplied headers above.
4895
- "solana-client": `js/${"2.3.0"}`
4896
- }
4897
- }
4898
- }),
4899
- (transport) => getRpcTransportWithRequestCoalescing(transport, getSolanaRpcPayloadDeduplicationKey)
4900
- );
4946
+ function encodeU643(value) {
4947
+ const out = Buffer.alloc(8);
4948
+ out.writeBigUInt64LE(value, 0);
4949
+ return out;
4901
4950
  }
4902
- function createSolanaRpc(clusterUrl, config) {
4903
- return createSolanaRpcFromTransport(createDefaultRpcTransport({ url: clusterUrl, ...config }));
4951
+ function encodeU322(value) {
4952
+ const out = Buffer.alloc(4);
4953
+ out.writeUInt32LE(value >>> 0, 0);
4954
+ return out;
4904
4955
  }
4905
- function createSolanaRpcFromTransport(transport) {
4906
- return createRpc({
4907
- api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),
4908
- transport
4956
+ function buildSettleTabVoucherInstruction(p) {
4957
+ if (p.channelId.length !== 32) {
4958
+ throw new Error(`channelId must be 32 bytes, got ${p.channelId.length}`);
4959
+ }
4960
+ const argsBuf = Buffer.concat([
4961
+ encodeFixedBytes2(p.channelId, 32),
4962
+ encodeU643(p.cumulativeAmount),
4963
+ encodeU322(p.sequenceNumber)
4964
+ ]);
4965
+ const data = Buffer.concat([Buffer.from(DISCRIMINATORS.settle_tab_voucher), argsBuf]);
4966
+ const swigWalletAddress = deriveSwigWalletAddress(p.swigAddress);
4967
+ return new TransactionInstruction8({
4968
+ programId: DEXTER_VAULT_PROGRAM_ID,
4969
+ keys: [
4970
+ { pubkey: p.swigAddress, isSigner: false, isWritable: false },
4971
+ { pubkey: swigWalletAddress, isSigner: false, isWritable: false },
4972
+ { pubkey: p.vaultPda, isSigner: false, isWritable: true },
4973
+ { pubkey: p.dexterAuthority, isSigner: true, isWritable: false },
4974
+ { pubkey: SYSVAR_INSTRUCTIONS_PUBKEY4, isSigner: false, isWritable: false }
4975
+ ],
4976
+ data
4909
4977
  });
4910
4978
  }
4911
4979
 
4912
- // src/instructions/swigBundle.ts
4913
- import * as bs58Module from "bs58";
4914
- import { PublicKey as PublicKey12 } from "@solana/web3.js";
4915
- var bs58 = bs58Module.default ?? bs58Module;
4916
- var SWIG_ID_DOMAIN = "dexter-swig-id:v1:";
4917
- var DEFAULT_SESSION_TTL_SECONDS = BigInt(30 * 24 * 60 * 60);
4918
- var DEFAULT_SPEND_LIMIT_ATOMIC = BigInt(1e9);
4919
- var SWIG_PROGRAM_EXEC_PREFIX = new Uint8Array([
4920
- 178,
4921
- 87,
4922
- 206,
4923
- 68,
4924
- 201,
4925
- 186,
4926
- 164,
4927
- 232
4928
- ]);
4929
- var SWIG_PROGRAM_EXEC_PREFIX_SETTLE_TAB = new Uint8Array([
4930
- 173,
4931
- 22,
4932
- 98,
4933
- 31,
4934
- 110,
4935
- 129,
4936
- 59,
4937
- 161
4938
- ]);
4939
- var SWIG_PROGRAM_EXEC_MARKERS = [
4940
- SWIG_PROGRAM_EXEC_PREFIX,
4941
- SWIG_PROGRAM_EXEC_PREFIX_SETTLE_TAB
4942
- ];
4943
- function deriveSwigId(identitySeed, hmacKey) {
4944
- if (hmacKey.length !== 32) {
4945
- throw new Error(`hmacKey must be 32 bytes, got ${hmacKey.length}`);
4980
+ // src/instructions/rotate.ts
4981
+ import {
4982
+ TransactionInstruction as TransactionInstruction9,
4983
+ SYSVAR_INSTRUCTIONS_PUBKEY as SYSVAR_INSTRUCTIONS_PUBKEY5
4984
+ } from "@solana/web3.js";
4985
+ function encodeBytesVec3(buf) {
4986
+ const out = Buffer.alloc(4 + buf.length);
4987
+ out.writeUInt32LE(buf.length, 0);
4988
+ Buffer.from(buf).copy(out, 4);
4989
+ return out;
4990
+ }
4991
+ function encodeFixedBytes3(buf, len) {
4992
+ if (buf.length !== len) {
4993
+ throw new Error(`expected ${len} bytes, got ${buf.length}`);
4946
4994
  }
4947
- return createHmac("sha256", Buffer.from(hmacKey)).update(SWIG_ID_DOMAIN).update(Buffer.from(identitySeed)).digest();
4995
+ return Buffer.from(buf);
4948
4996
  }
4949
- async function buildSwigCreationBundle(params) {
4950
- const {
4951
- feePayer,
4952
- dexterMasterPubkey,
4953
- identitySeed,
4954
- hmacKey,
4955
- sessionTtlSeconds = DEFAULT_SESSION_TTL_SECONDS,
4956
- spendLimitAtomic = DEFAULT_SPEND_LIMIT_ATOMIC
4957
- } = params;
4958
- const swigId = deriveSwigId(identitySeed, hmacKey);
4959
- const swigPda = await findSwigPda(swigId);
4960
- const swigAddressStr = String(swigPda);
4961
- const feePayerBytes = bs58.decode(feePayer);
4962
- const vaultProgramIdBytes = Uint8Array.from(DEXTER_VAULT_PROGRAM_ID.toBytes());
4963
- const dexterPubkeyBytes = bs58.decode(dexterMasterPubkey);
4964
- const bootstrapAuthorityInfo = createEd25519AuthorityInfo(feePayerBytes);
4965
- const bootstrapActions = Actions.set().manageAuthority().get();
4966
- const vaultAuthorityInfo = createProgramExecAuthorityInfo(
4967
- vaultProgramIdBytes,
4968
- SWIG_PROGRAM_EXEC_PREFIX
4969
- );
4970
- const vaultActions = Actions.set().all().get();
4971
- const vaultTabSettleAuthorityInfo = createProgramExecAuthorityInfo(
4972
- vaultProgramIdBytes,
4973
- SWIG_PROGRAM_EXEC_PREFIX_SETTLE_TAB
4974
- );
4975
- const vaultTabSettleActions = Actions.set().all().get();
4976
- const sessionAuthorityInfo = createEd25519SessionAuthorityInfo(
4977
- dexterPubkeyBytes,
4978
- sessionTtlSeconds
4979
- );
4980
- const sessionActions = Actions.set().tokenLimit({ mint: bs58.decode(USDC_MAINNET), amount: spendLimitAtomic }).programAll().get();
4981
- const builder = getCreateSwigWithMultipleAuthoritiesInstructionContextBuilder({
4982
- payer: address(feePayer),
4983
- swigAddress: address(swigAddressStr),
4984
- id: swigId,
4985
- actions: bootstrapActions,
4986
- authorityInfo: bootstrapAuthorityInfo,
4987
- options: {}
4988
- }).addAuthority(vaultAuthorityInfo, vaultActions).addAuthority(sessionAuthorityInfo, sessionActions).addAuthority(vaultTabSettleAuthorityInfo, vaultTabSettleActions);
4989
- const contexts = await builder.getInstructionContexts();
4990
- const instructions = contexts.flatMap((ctx) => getInstructionsFromContext(ctx));
4991
- return {
4992
- swigAddress: swigAddressStr,
4993
- swigIdBase58: bs58.encode(swigId),
4994
- instructions
4995
- };
4997
+ function encodePubkey3(key) {
4998
+ return Buffer.from(key.toBytes());
4996
4999
  }
4997
- async function expectedSwigAddressFor(identitySeed, hmacKey) {
4998
- const swigId = deriveSwigId(identitySeed, hmacKey);
4999
- return String(await findSwigPda(swigId));
5000
+ function buildRotatePasskeyInstruction(p) {
5001
+ const argsBuf = Buffer.concat([
5002
+ encodeFixedBytes3(p.newPasskeyPubkey, 33),
5003
+ encodeBytesVec3(p.clientDataJSON),
5004
+ encodeBytesVec3(p.authenticatorData)
5005
+ ]);
5006
+ const data = Buffer.concat([Buffer.from(DISCRIMINATORS.rotate_passkey), argsBuf]);
5007
+ return new TransactionInstruction9({
5008
+ programId: DEXTER_VAULT_PROGRAM_ID,
5009
+ keys: [
5010
+ { pubkey: p.vaultPda, isSigner: false, isWritable: true },
5011
+ { pubkey: SYSVAR_INSTRUCTIONS_PUBKEY5, isSigner: false, isWritable: false }
5012
+ ],
5013
+ data
5014
+ });
5000
5015
  }
5001
- async function verifySwigIsOurs(params) {
5002
- const { swigAddress, identitySeed, hmacKey, dexterMasterPubkey, rpcEndpoint } = params;
5003
- const expected = await expectedSwigAddressFor(identitySeed, hmacKey);
5004
- if (swigAddress !== expected) {
5005
- return {
5006
- ok: false,
5007
- reason: `swig_address_mismatch: expected ${expected}, got ${swigAddress}`
5008
- };
5009
- }
5010
- try {
5011
- const rpc = createSolanaRpc(rpcEndpoint);
5012
- const swig = await fetchNullableSwig(rpc, address(swigAddress));
5013
- if (swig) {
5014
- const ourRoles = swig.findRolesByAuthorityAddress(bs58.decode(dexterMasterPubkey));
5015
- if (!ourRoles || ourRoles.length === 0) {
5016
- return {
5017
- ok: false,
5018
- reason: "swig_missing_session_master_role"
5019
- };
5020
- }
5021
- }
5022
- } catch {
5023
- }
5024
- return { ok: true };
5016
+ function buildRotateDexterAuthorityInstruction(p) {
5017
+ const data = Buffer.concat([
5018
+ Buffer.from(DISCRIMINATORS.rotate_dexter_authority),
5019
+ encodePubkey3(p.newDexterAuthority)
5020
+ ]);
5021
+ return new TransactionInstruction9({
5022
+ programId: DEXTER_VAULT_PROGRAM_ID,
5023
+ keys: [
5024
+ { pubkey: p.vaultPda, isSigner: false, isWritable: true },
5025
+ { pubkey: p.currentDexterAuthority, isSigner: true, isWritable: false }
5026
+ ],
5027
+ data
5028
+ });
5025
5029
  }
5026
- function deriveVaultPda(supabaseUserId) {
5027
- if (supabaseUserId.length !== 16) {
5028
- throw new Error("supabaseUserId must be 16 bytes (UUID v4)");
5030
+
5031
+ // src/instructions/provePasskey.ts
5032
+ import {
5033
+ TransactionInstruction as TransactionInstruction10,
5034
+ SYSVAR_INSTRUCTIONS_PUBKEY as SYSVAR_INSTRUCTIONS_PUBKEY6
5035
+ } from "@solana/web3.js";
5036
+ function encodeBytesVec4(buf) {
5037
+ const out = Buffer.alloc(4 + buf.length);
5038
+ out.writeUInt32LE(buf.length, 0);
5039
+ Buffer.from(buf).copy(out, 4);
5040
+ return out;
5041
+ }
5042
+ function encodeFixedBytes4(buf, len) {
5043
+ if (buf.length !== len) {
5044
+ throw new Error(`expected ${len} bytes, got ${buf.length}`);
5029
5045
  }
5030
- const [pda, bump] = PublicKey12.findProgramAddressSync(
5031
- [Buffer.from("vault"), Buffer.from(supabaseUserId)],
5032
- DEXTER_VAULT_PROGRAM_ID
5033
- );
5034
- return { pda, bump };
5046
+ return Buffer.from(buf);
5047
+ }
5048
+ function buildProvePasskeyInstruction(p) {
5049
+ const argsBuf = Buffer.concat([
5050
+ encodeFixedBytes4(p.challenge, 32),
5051
+ encodeBytesVec4(p.clientDataJSON),
5052
+ encodeBytesVec4(p.authenticatorData)
5053
+ ]);
5054
+ const data = Buffer.concat([Buffer.from(DISCRIMINATORS.prove_passkey), argsBuf]);
5055
+ return new TransactionInstruction10({
5056
+ programId: DEXTER_VAULT_PROGRAM_ID,
5057
+ keys: [
5058
+ { pubkey: p.vaultPda, isSigner: false, isWritable: false },
5059
+ { pubkey: SYSVAR_INSTRUCTIONS_PUBKEY6, isSigner: false, isWritable: false }
5060
+ ],
5061
+ data
5062
+ });
5035
5063
  }
5036
5064
  export {
5037
5065
  SET_SWIG_ATOMIC_DISCRIMINATOR,
@@ -5047,11 +5075,13 @@ export {
5047
5075
  buildRevokeSessionKeyInstruction,
5048
5076
  buildRotateDexterAuthorityInstruction,
5049
5077
  buildRotatePasskeyInstruction,
5078
+ buildSetSwigAtomicFromIdentity,
5050
5079
  buildSetSwigAtomicInstruction,
5051
5080
  buildSetSwigInstruction,
5052
5081
  buildSettleTabVoucherInstruction,
5053
5082
  buildSettleVoucherInstruction,
5054
5083
  buildSwigCreationBundle,
5084
+ deriveSwigId,
5055
5085
  deriveSwigWalletAddress,
5056
5086
  deriveVaultPda,
5057
5087
  expectedSwigAddressFor,