@dexterai/vault 0.4.1 → 0.5.0
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 +62 -16
- package/dist/constants/index.cjs +13 -1
- package/dist/constants/index.d.cts +11 -1
- package/dist/constants/index.d.ts +11 -1
- package/dist/constants/index.js +12 -1
- package/dist/counterfactual.cjs +12 -1
- package/dist/counterfactual.js +12 -1
- package/dist/factoring/index.cjs +246 -0
- package/dist/factoring/index.d.cts +79 -0
- package/dist/factoring/index.d.ts +79 -0
- package/dist/factoring/index.js +220 -0
- package/dist/idl/dexter_vault.json +976 -1
- package/dist/index.cjs +12 -1
- package/dist/index.js +12 -1
- package/dist/instructions/index.cjs +368 -4514
- package/dist/instructions/index.d.cts +190 -3
- package/dist/instructions/index.d.ts +190 -3
- package/dist/instructions/index.js +367 -4523
- package/dist/kit/index.cjs +67 -0
- package/dist/kit/index.d.cts +13 -0
- package/dist/kit/index.d.ts +13 -0
- package/dist/kit/index.js +41 -0
- package/dist/messages/index.cjs +11 -1
- package/dist/messages/index.js +11 -1
- package/dist/precompile/index.cjs +11 -1
- package/dist/precompile/index.js +11 -1
- package/dist/tab/index.cjs +640 -0
- package/dist/tab/index.d.cts +145 -0
- package/dist/tab/index.d.ts +145 -0
- package/dist/tab/index.js +631 -0
- package/package.json +102 -17
|
@@ -0,0 +1,640 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/tab/index.ts
|
|
31
|
+
var tab_exports = {};
|
|
32
|
+
__export(tab_exports, {
|
|
33
|
+
defaultAssembleSignV2: () => defaultAssembleSignV2,
|
|
34
|
+
drawCredit: () => drawCredit,
|
|
35
|
+
openTab: () => openTab,
|
|
36
|
+
readTabMeter: () => readTabMeter,
|
|
37
|
+
repayCredit: () => repayCredit,
|
|
38
|
+
seizeCollateral: () => seizeCollateral,
|
|
39
|
+
settleTab: () => settleTab
|
|
40
|
+
});
|
|
41
|
+
module.exports = __toCommonJS(tab_exports);
|
|
42
|
+
|
|
43
|
+
// src/instructions/initialize.ts
|
|
44
|
+
var import_web32 = require("@solana/web3.js");
|
|
45
|
+
|
|
46
|
+
// src/constants/index.ts
|
|
47
|
+
var import_web3 = require("@solana/web3.js");
|
|
48
|
+
var DEXTER_VAULT_PROGRAM_ID = new import_web3.PublicKey(
|
|
49
|
+
"Hg3wRaydFtJhYrdvYrKECacpJYDsC9Px7yKmpncj2fhc"
|
|
50
|
+
);
|
|
51
|
+
var SWIG_PROGRAM_ID = new import_web3.PublicKey(
|
|
52
|
+
"swigypWHEksbC64pWKwah1WTeh9JXwx8H1rJHLdbQMB"
|
|
53
|
+
);
|
|
54
|
+
var SECP256R1_PROGRAM_ID = new import_web3.PublicKey(
|
|
55
|
+
"Secp256r1SigVerify1111111111111111111111111"
|
|
56
|
+
);
|
|
57
|
+
var ED25519_PROGRAM_ID = new import_web3.PublicKey(
|
|
58
|
+
"Ed25519SigVerify111111111111111111111111111"
|
|
59
|
+
);
|
|
60
|
+
var INSTRUCTIONS_SYSVAR_ID = new import_web3.PublicKey(
|
|
61
|
+
"Sysvar1nstructions1111111111111111111111111"
|
|
62
|
+
);
|
|
63
|
+
var USDC_MAINNET = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
|
|
64
|
+
var VAULT_SEED_PREFIX = Buffer.from("vault");
|
|
65
|
+
var LOCKED_CLAIM_SEED = Buffer.from("locked-claim");
|
|
66
|
+
var DISCRIMINATORS = Object.freeze({
|
|
67
|
+
initialize_vault: Uint8Array.from([48, 191, 163, 44, 71, 129, 63, 164]),
|
|
68
|
+
set_swig: Uint8Array.from([253, 229, 89, 206, 192, 118, 137, 165]),
|
|
69
|
+
settle_voucher: Uint8Array.from([144, 176, 128, 220, 156, 79, 41, 54]),
|
|
70
|
+
request_withdrawal: Uint8Array.from([251, 85, 121, 205, 56, 201, 12, 177]),
|
|
71
|
+
finalize_withdrawal: Uint8Array.from([178, 87, 206, 68, 201, 186, 164, 232]),
|
|
72
|
+
force_release: Uint8Array.from([122, 190, 243, 252, 54, 202, 208, 234]),
|
|
73
|
+
rotate_passkey: Uint8Array.from([28, 134, 49, 89, 196, 34, 58, 174]),
|
|
74
|
+
rotate_dexter_authority: Uint8Array.from([145, 60, 4, 119, 180, 205, 236, 134]),
|
|
75
|
+
prove_passkey: Uint8Array.from([35, 175, 41, 143, 201, 118, 49, 184]),
|
|
76
|
+
settle_tab_voucher: Uint8Array.from([173, 22, 98, 31, 110, 129, 59, 161]),
|
|
77
|
+
register_session_key: Uint8Array.from([69, 94, 60, 44, 49, 199, 183, 233]),
|
|
78
|
+
revoke_session_key: Uint8Array.from([81, 192, 32, 110, 104, 116, 144, 151]),
|
|
79
|
+
lock_voucher: Uint8Array.from([91, 138, 5, 227, 119, 239, 48, 254]),
|
|
80
|
+
settle_locked_voucher: Uint8Array.from([44, 80, 216, 43, 247, 253, 101, 45]),
|
|
81
|
+
transfer_lock_ownership: Uint8Array.from([193, 13, 131, 134, 95, 25, 229, 157]),
|
|
82
|
+
recover_abandoned_lock: Uint8Array.from([169, 213, 107, 64, 229, 49, 43, 234]),
|
|
83
|
+
open_standby: Uint8Array.from([234, 184, 232, 135, 246, 191, 90, 250]),
|
|
84
|
+
draw_credit: Uint8Array.from([20, 84, 47, 211, 78, 117, 195, 210]),
|
|
85
|
+
repay_credit: Uint8Array.from([38, 113, 240, 182, 109, 179, 154, 245]),
|
|
86
|
+
seize_collateral: Uint8Array.from([40, 250, 7, 243, 168, 184, 116, 154]),
|
|
87
|
+
migrate_v4_to_v5: Uint8Array.from([226, 105, 140, 184, 101, 39, 235, 116])
|
|
88
|
+
});
|
|
89
|
+
var OTS_SESSION_REGISTER_V1_DOMAIN = (() => {
|
|
90
|
+
const buf = new Uint8Array(32);
|
|
91
|
+
buf.set(new TextEncoder().encode("OTS_SESSION_REGISTER_V1"), 0);
|
|
92
|
+
return buf;
|
|
93
|
+
})();
|
|
94
|
+
var OTS_SESSION_REGISTER_V2_DOMAIN = (() => {
|
|
95
|
+
const buf = new Uint8Array(32);
|
|
96
|
+
buf.set(new TextEncoder().encode("OTS_SESSION_REGISTER_V2"), 0);
|
|
97
|
+
return buf;
|
|
98
|
+
})();
|
|
99
|
+
var OTS_SESSION_REVOKE_V1_DOMAIN = (() => {
|
|
100
|
+
const buf = new Uint8Array(32);
|
|
101
|
+
buf.set(new TextEncoder().encode("OTS_SESSION_REVOKE_V1"), 0);
|
|
102
|
+
return buf;
|
|
103
|
+
})();
|
|
104
|
+
|
|
105
|
+
// src/instructions/setSwig.ts
|
|
106
|
+
var import_web33 = require("@solana/web3.js");
|
|
107
|
+
|
|
108
|
+
// src/instructions/setSwigAtomic.ts
|
|
109
|
+
var import_web35 = require("@solana/web3.js");
|
|
110
|
+
|
|
111
|
+
// src/instructions/swigBundle.ts
|
|
112
|
+
var import_node_crypto = require("crypto");
|
|
113
|
+
var import_kit = require("@swig-wallet/kit");
|
|
114
|
+
var import_lib = require("@swig-wallet/lib");
|
|
115
|
+
var import_kit2 = require("@solana/kit");
|
|
116
|
+
var bs58Module = __toESM(require("bs58"), 1);
|
|
117
|
+
var import_web34 = require("@solana/web3.js");
|
|
118
|
+
var DEFAULT_SESSION_TTL_SECONDS = BigInt(30 * 24 * 60 * 60);
|
|
119
|
+
var DEFAULT_SPEND_LIMIT_ATOMIC = BigInt(1e9);
|
|
120
|
+
var SWIG_PROGRAM_EXEC_PREFIX = new Uint8Array([
|
|
121
|
+
178,
|
|
122
|
+
87,
|
|
123
|
+
206,
|
|
124
|
+
68,
|
|
125
|
+
201,
|
|
126
|
+
186,
|
|
127
|
+
164,
|
|
128
|
+
232
|
|
129
|
+
]);
|
|
130
|
+
var SWIG_PROGRAM_EXEC_PREFIX_SETTLE_TAB = new Uint8Array([
|
|
131
|
+
173,
|
|
132
|
+
22,
|
|
133
|
+
98,
|
|
134
|
+
31,
|
|
135
|
+
110,
|
|
136
|
+
129,
|
|
137
|
+
59,
|
|
138
|
+
161
|
|
139
|
+
]);
|
|
140
|
+
|
|
141
|
+
// src/instructions/setSwigAtomic.ts
|
|
142
|
+
var SET_SWIG_ATOMIC_DISCRIMINATOR = new Uint8Array([
|
|
143
|
+
119,
|
|
144
|
+
111,
|
|
145
|
+
247,
|
|
146
|
+
215,
|
|
147
|
+
190,
|
|
148
|
+
3,
|
|
149
|
+
170,
|
|
150
|
+
23
|
|
151
|
+
]);
|
|
152
|
+
|
|
153
|
+
// src/instructions/registerSession.ts
|
|
154
|
+
var import_web37 = require("@solana/web3.js");
|
|
155
|
+
|
|
156
|
+
// src/instructions/withdraw.ts
|
|
157
|
+
var import_web36 = require("@solana/web3.js");
|
|
158
|
+
function deriveSwigWalletAddress(swigAddress) {
|
|
159
|
+
const [pda] = import_web36.PublicKey.findProgramAddressSync(
|
|
160
|
+
[Buffer.from("swig-wallet-address"), swigAddress.toBuffer()],
|
|
161
|
+
SWIG_PROGRAM_ID
|
|
162
|
+
);
|
|
163
|
+
return pda;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// src/instructions/revokeSession.ts
|
|
167
|
+
var import_web38 = require("@solana/web3.js");
|
|
168
|
+
|
|
169
|
+
// src/instructions/settleVoucher.ts
|
|
170
|
+
var import_web39 = require("@solana/web3.js");
|
|
171
|
+
function encodeU64(value) {
|
|
172
|
+
const out = Buffer.alloc(8);
|
|
173
|
+
out.writeBigUInt64LE(value, 0);
|
|
174
|
+
return out;
|
|
175
|
+
}
|
|
176
|
+
function encodeBool(value) {
|
|
177
|
+
return Buffer.from([value ? 1 : 0]);
|
|
178
|
+
}
|
|
179
|
+
function buildSettleVoucherInstruction(p) {
|
|
180
|
+
const argsBuf = Buffer.concat([encodeU64(p.amount), encodeBool(p.increment)]);
|
|
181
|
+
const data = Buffer.concat([Buffer.from(DISCRIMINATORS.settle_voucher), argsBuf]);
|
|
182
|
+
return new import_web39.TransactionInstruction({
|
|
183
|
+
programId: DEXTER_VAULT_PROGRAM_ID,
|
|
184
|
+
keys: [
|
|
185
|
+
{ pubkey: p.vaultPda, isSigner: false, isWritable: true },
|
|
186
|
+
{ pubkey: p.dexterAuthority, isSigner: true, isWritable: false }
|
|
187
|
+
],
|
|
188
|
+
data
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// src/instructions/settleTabVoucher.ts
|
|
193
|
+
var import_web310 = require("@solana/web3.js");
|
|
194
|
+
function encodeFixedBytes(buf, len) {
|
|
195
|
+
if (buf.length !== len) {
|
|
196
|
+
throw new Error(`expected ${len} bytes, got ${buf.length}`);
|
|
197
|
+
}
|
|
198
|
+
return Buffer.from(buf);
|
|
199
|
+
}
|
|
200
|
+
function encodeU642(value) {
|
|
201
|
+
const out = Buffer.alloc(8);
|
|
202
|
+
out.writeBigUInt64LE(value, 0);
|
|
203
|
+
return out;
|
|
204
|
+
}
|
|
205
|
+
function encodeU32(value) {
|
|
206
|
+
const out = Buffer.alloc(4);
|
|
207
|
+
out.writeUInt32LE(value >>> 0, 0);
|
|
208
|
+
return out;
|
|
209
|
+
}
|
|
210
|
+
function buildSettleTabVoucherInstruction(p) {
|
|
211
|
+
if (p.channelId.length !== 32) {
|
|
212
|
+
throw new Error(`channelId must be 32 bytes, got ${p.channelId.length}`);
|
|
213
|
+
}
|
|
214
|
+
const argsBuf = Buffer.concat([
|
|
215
|
+
encodeFixedBytes(p.channelId, 32),
|
|
216
|
+
encodeU642(p.cumulativeAmount),
|
|
217
|
+
encodeU32(p.sequenceNumber)
|
|
218
|
+
]);
|
|
219
|
+
const data = Buffer.concat([Buffer.from(DISCRIMINATORS.settle_tab_voucher), argsBuf]);
|
|
220
|
+
const swigWalletAddress = deriveSwigWalletAddress(p.swigAddress);
|
|
221
|
+
return new import_web310.TransactionInstruction({
|
|
222
|
+
programId: DEXTER_VAULT_PROGRAM_ID,
|
|
223
|
+
keys: [
|
|
224
|
+
{ pubkey: p.swigAddress, isSigner: false, isWritable: false },
|
|
225
|
+
{ pubkey: swigWalletAddress, isSigner: false, isWritable: false },
|
|
226
|
+
{ pubkey: p.vaultPda, isSigner: false, isWritable: true },
|
|
227
|
+
{ pubkey: p.dexterAuthority, isSigner: true, isWritable: false },
|
|
228
|
+
{ pubkey: import_web310.SYSVAR_INSTRUCTIONS_PUBKEY, isSigner: false, isWritable: false }
|
|
229
|
+
],
|
|
230
|
+
data
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// src/instructions/rotate.ts
|
|
235
|
+
var import_web311 = require("@solana/web3.js");
|
|
236
|
+
|
|
237
|
+
// src/instructions/provePasskey.ts
|
|
238
|
+
var import_web312 = require("@solana/web3.js");
|
|
239
|
+
|
|
240
|
+
// src/instructions/lockedClaim.ts
|
|
241
|
+
var import_web313 = require("@solana/web3.js");
|
|
242
|
+
|
|
243
|
+
// src/instructions/credit.ts
|
|
244
|
+
var import_web314 = require("@solana/web3.js");
|
|
245
|
+
function encodeU643(value) {
|
|
246
|
+
const out = Buffer.alloc(8);
|
|
247
|
+
out.writeBigUInt64LE(value, 0);
|
|
248
|
+
return out;
|
|
249
|
+
}
|
|
250
|
+
function encodeI64(value) {
|
|
251
|
+
const out = Buffer.alloc(8);
|
|
252
|
+
out.writeBigInt64LE(value, 0);
|
|
253
|
+
return out;
|
|
254
|
+
}
|
|
255
|
+
function buildDrawCreditInstruction(p) {
|
|
256
|
+
const data = Buffer.concat([
|
|
257
|
+
Buffer.from(DISCRIMINATORS.draw_credit),
|
|
258
|
+
encodeU643(p.amount),
|
|
259
|
+
encodeI64(p.recoveryWindowSeconds)
|
|
260
|
+
]);
|
|
261
|
+
const financierSwigWalletAddress = deriveSwigWalletAddress(p.financierSwig);
|
|
262
|
+
return new import_web314.TransactionInstruction({
|
|
263
|
+
programId: DEXTER_VAULT_PROGRAM_ID,
|
|
264
|
+
keys: [
|
|
265
|
+
{ pubkey: p.financierSwig, isSigner: false, isWritable: false },
|
|
266
|
+
{ pubkey: financierSwigWalletAddress, isSigner: false, isWritable: false },
|
|
267
|
+
{ pubkey: p.vaultPda, isSigner: false, isWritable: true },
|
|
268
|
+
{ pubkey: p.dexterAuthority, isSigner: true, isWritable: false },
|
|
269
|
+
{ pubkey: INSTRUCTIONS_SYSVAR_ID, isSigner: false, isWritable: false }
|
|
270
|
+
],
|
|
271
|
+
data
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
function buildRepayCreditInstruction(p) {
|
|
275
|
+
const data = Buffer.concat([
|
|
276
|
+
Buffer.from(DISCRIMINATORS.repay_credit),
|
|
277
|
+
encodeU643(p.amount)
|
|
278
|
+
]);
|
|
279
|
+
const swigWalletAddress = deriveSwigWalletAddress(p.swigAddress);
|
|
280
|
+
return new import_web314.TransactionInstruction({
|
|
281
|
+
programId: DEXTER_VAULT_PROGRAM_ID,
|
|
282
|
+
keys: [
|
|
283
|
+
{ pubkey: p.swigAddress, isSigner: false, isWritable: false },
|
|
284
|
+
{ pubkey: swigWalletAddress, isSigner: false, isWritable: false },
|
|
285
|
+
{ pubkey: p.vaultPda, isSigner: false, isWritable: true },
|
|
286
|
+
{ pubkey: p.dexterAuthority, isSigner: true, isWritable: false },
|
|
287
|
+
{ pubkey: INSTRUCTIONS_SYSVAR_ID, isSigner: false, isWritable: false }
|
|
288
|
+
],
|
|
289
|
+
data
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
function buildSeizeCollateralInstruction(p) {
|
|
293
|
+
const data = Buffer.from(DISCRIMINATORS.seize_collateral);
|
|
294
|
+
const swigWalletAddress = deriveSwigWalletAddress(p.swigAddress);
|
|
295
|
+
return new import_web314.TransactionInstruction({
|
|
296
|
+
programId: DEXTER_VAULT_PROGRAM_ID,
|
|
297
|
+
keys: [
|
|
298
|
+
{ pubkey: p.swigAddress, isSigner: false, isWritable: false },
|
|
299
|
+
{ pubkey: swigWalletAddress, isSigner: false, isWritable: false },
|
|
300
|
+
{ pubkey: p.vaultPda, isSigner: false, isWritable: true },
|
|
301
|
+
{ pubkey: p.dexterAuthority, isSigner: true, isWritable: false },
|
|
302
|
+
{ pubkey: INSTRUCTIONS_SYSVAR_ID, isSigner: false, isWritable: false }
|
|
303
|
+
],
|
|
304
|
+
data
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// src/tab/openTab.ts
|
|
309
|
+
async function openTab(p) {
|
|
310
|
+
const ix = buildSettleVoucherInstruction({
|
|
311
|
+
vaultPda: p.vaultPda,
|
|
312
|
+
amount: p.amount,
|
|
313
|
+
increment: true,
|
|
314
|
+
dexterAuthority: p.dexterAuthority
|
|
315
|
+
});
|
|
316
|
+
return [ix];
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// src/messages/voucher.ts
|
|
320
|
+
function voucherPayloadMessage(p) {
|
|
321
|
+
if (p.channelId.length !== 32) {
|
|
322
|
+
throw new Error(`channelId must be 32 bytes, got ${p.channelId.length}`);
|
|
323
|
+
}
|
|
324
|
+
const buf = new Uint8Array(44);
|
|
325
|
+
const view = new DataView(buf.buffer);
|
|
326
|
+
buf.set(p.channelId, 0);
|
|
327
|
+
view.setBigUint64(32, p.cumulativeAmount, true);
|
|
328
|
+
view.setUint32(40, p.sequenceNumber >>> 0, true);
|
|
329
|
+
return buf;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// src/messages/operations.ts
|
|
333
|
+
var import_web315 = require("@solana/web3.js");
|
|
334
|
+
|
|
335
|
+
// src/precompile/secp256r1.ts
|
|
336
|
+
var import_web316 = require("@solana/web3.js");
|
|
337
|
+
|
|
338
|
+
// src/precompile/ed25519.ts
|
|
339
|
+
var import_web317 = require("@solana/web3.js");
|
|
340
|
+
function buildEd25519VerifyInstruction(pubkey, signature, message) {
|
|
341
|
+
if (pubkey.length !== 32) throw new Error("pubkey must be 32 bytes");
|
|
342
|
+
if (signature.length !== 64) throw new Error("signature must be 64 bytes");
|
|
343
|
+
const NUM_SIG = 1;
|
|
344
|
+
const PADDING = 0;
|
|
345
|
+
const HEADER_LEN = 2;
|
|
346
|
+
const OFFSETS_LEN = 14;
|
|
347
|
+
const DATA_START = HEADER_LEN + OFFSETS_LEN;
|
|
348
|
+
const data = Buffer.alloc(DATA_START + pubkey.length + signature.length + message.length);
|
|
349
|
+
let off = 0;
|
|
350
|
+
data.writeUInt8(NUM_SIG, off);
|
|
351
|
+
off += 1;
|
|
352
|
+
data.writeUInt8(PADDING, off);
|
|
353
|
+
off += 1;
|
|
354
|
+
const pubkeyOffset = DATA_START;
|
|
355
|
+
const signatureOffset = pubkeyOffset + pubkey.length;
|
|
356
|
+
const messageOffset = signatureOffset + signature.length;
|
|
357
|
+
data.writeUInt16LE(signatureOffset, off);
|
|
358
|
+
off += 2;
|
|
359
|
+
data.writeUInt16LE(65535, off);
|
|
360
|
+
off += 2;
|
|
361
|
+
data.writeUInt16LE(pubkeyOffset, off);
|
|
362
|
+
off += 2;
|
|
363
|
+
data.writeUInt16LE(65535, off);
|
|
364
|
+
off += 2;
|
|
365
|
+
data.writeUInt16LE(messageOffset, off);
|
|
366
|
+
off += 2;
|
|
367
|
+
data.writeUInt16LE(message.length, off);
|
|
368
|
+
off += 2;
|
|
369
|
+
data.writeUInt16LE(65535, off);
|
|
370
|
+
off += 2;
|
|
371
|
+
Buffer.from(pubkey).copy(data, pubkeyOffset);
|
|
372
|
+
Buffer.from(signature).copy(data, signatureOffset);
|
|
373
|
+
Buffer.from(message).copy(data, messageOffset);
|
|
374
|
+
return new import_web317.TransactionInstruction({
|
|
375
|
+
programId: ED25519_PROGRAM_ID,
|
|
376
|
+
keys: [],
|
|
377
|
+
data
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// src/reader/accountReader.ts
|
|
382
|
+
var import_web318 = require("@solana/web3.js");
|
|
383
|
+
var VERSION_OFFSET = 8;
|
|
384
|
+
var SWIG_ADDRESS_OFFSET = 43;
|
|
385
|
+
var PENDING_VOUCHER_COUNT_OFFSET = 79;
|
|
386
|
+
var PENDING_WITHDRAWAL_TAG_OFFSET = 83;
|
|
387
|
+
var PENDING_WITHDRAWAL_BODY_LEN = 48;
|
|
388
|
+
var PENDING_WITHDRAWAL_BODY_START = PENDING_WITHDRAWAL_TAG_OFFSET + 1;
|
|
389
|
+
var IDENTITY_CLAIM_LEN = 32;
|
|
390
|
+
var PUBKEY_LEN = 32;
|
|
391
|
+
var ACTIVE_SESSION_BODY_LEN = 92;
|
|
392
|
+
var EMPTY_FULL = {
|
|
393
|
+
exists: false,
|
|
394
|
+
version: 0,
|
|
395
|
+
swigAddress: null,
|
|
396
|
+
dexterAuthority: null,
|
|
397
|
+
pendingVoucherCount: 0,
|
|
398
|
+
activeSession: null
|
|
399
|
+
};
|
|
400
|
+
async function readVaultFull(conn, vaultPda) {
|
|
401
|
+
const account = await conn.getAccountInfo(vaultPda, "confirmed");
|
|
402
|
+
if (!account) return EMPTY_FULL;
|
|
403
|
+
const data = account.data;
|
|
404
|
+
if (data.length < SWIG_ADDRESS_OFFSET + PUBKEY_LEN) return EMPTY_FULL;
|
|
405
|
+
const version = data.readUInt8(VERSION_OFFSET);
|
|
406
|
+
const swigAddress = new import_web318.PublicKey(
|
|
407
|
+
data.subarray(SWIG_ADDRESS_OFFSET, SWIG_ADDRESS_OFFSET + PUBKEY_LEN)
|
|
408
|
+
).toBase58();
|
|
409
|
+
const pendingVoucherCount = data.readUInt32LE(PENDING_VOUCHER_COUNT_OFFSET);
|
|
410
|
+
const withdrawalTag = data[PENDING_WITHDRAWAL_TAG_OFFSET];
|
|
411
|
+
const afterWithdrawal = PENDING_WITHDRAWAL_BODY_START + (withdrawalTag === 1 ? PENDING_WITHDRAWAL_BODY_LEN : 0);
|
|
412
|
+
const dexterAuthorityOffset = afterWithdrawal + IDENTITY_CLAIM_LEN;
|
|
413
|
+
if (data.length < dexterAuthorityOffset + PUBKEY_LEN) {
|
|
414
|
+
return { ...EMPTY_FULL, exists: true, version, swigAddress, pendingVoucherCount };
|
|
415
|
+
}
|
|
416
|
+
const dexterAuthority = new import_web318.PublicKey(
|
|
417
|
+
data.subarray(dexterAuthorityOffset, dexterAuthorityOffset + PUBKEY_LEN)
|
|
418
|
+
).toBase58();
|
|
419
|
+
const activeSessionTagOffset = dexterAuthorityOffset + PUBKEY_LEN;
|
|
420
|
+
let activeSession = null;
|
|
421
|
+
if (data.length > activeSessionTagOffset && data[activeSessionTagOffset] === 1) {
|
|
422
|
+
const bodyStart = activeSessionTagOffset + 1;
|
|
423
|
+
if (data.length >= bodyStart + ACTIVE_SESSION_BODY_LEN) {
|
|
424
|
+
activeSession = {
|
|
425
|
+
sessionPubkey: new Uint8Array(data.subarray(bodyStart, bodyStart + 32)),
|
|
426
|
+
maxAmount: data.readBigUInt64LE(bodyStart + 32),
|
|
427
|
+
expiresAt: Number(data.readBigInt64LE(bodyStart + 40)),
|
|
428
|
+
allowedCounterparty: new import_web318.PublicKey(
|
|
429
|
+
data.subarray(bodyStart + 48, bodyStart + 80)
|
|
430
|
+
).toBase58(),
|
|
431
|
+
nonce: data.readUInt32LE(bodyStart + 80),
|
|
432
|
+
spent: data.readBigUInt64LE(bodyStart + 84)
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
return {
|
|
437
|
+
exists: true,
|
|
438
|
+
version,
|
|
439
|
+
swigAddress,
|
|
440
|
+
dexterAuthority,
|
|
441
|
+
pendingVoucherCount,
|
|
442
|
+
activeSession
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// src/tab/assembleSignV2.ts
|
|
447
|
+
var import_web320 = require("@solana/web3.js");
|
|
448
|
+
var import_kit4 = require("@swig-wallet/kit");
|
|
449
|
+
var import_kit5 = require("@solana/kit");
|
|
450
|
+
var import_token = require("@solana-program/token");
|
|
451
|
+
var import_spl_token = require("@solana/spl-token");
|
|
452
|
+
|
|
453
|
+
// src/kit/index.ts
|
|
454
|
+
var import_web319 = require("@solana/web3.js");
|
|
455
|
+
var import_kit3 = require("@solana/kit");
|
|
456
|
+
function kitInstructionsToWeb3(kitInstructions) {
|
|
457
|
+
return kitInstructions.map((ix) => {
|
|
458
|
+
const accounts = (ix.accounts ?? []).map((acc) => {
|
|
459
|
+
const role = acc.role;
|
|
460
|
+
const hasBooleanShape = typeof acc.signer === "boolean" || typeof acc.writable === "boolean";
|
|
461
|
+
let isSigner = false;
|
|
462
|
+
let isWritable = false;
|
|
463
|
+
if (hasBooleanShape) {
|
|
464
|
+
isSigner = Boolean(acc.signer);
|
|
465
|
+
isWritable = Boolean(acc.writable);
|
|
466
|
+
} else if (typeof role === "number") {
|
|
467
|
+
isSigner = role >= 2;
|
|
468
|
+
isWritable = role % 2 === 1;
|
|
469
|
+
} else if (typeof role === "string") {
|
|
470
|
+
const r = role.toLowerCase();
|
|
471
|
+
isSigner = r.endsWith("signer");
|
|
472
|
+
isWritable = r.startsWith("writable");
|
|
473
|
+
}
|
|
474
|
+
const addressSource = acc.address ?? acc.publicKey;
|
|
475
|
+
const pubkey = addressSource instanceof import_web319.PublicKey ? addressSource : typeof addressSource === "string" ? new import_web319.PublicKey(addressSource) : new import_web319.PublicKey(String(addressSource));
|
|
476
|
+
return { pubkey, isSigner, isWritable };
|
|
477
|
+
});
|
|
478
|
+
return new import_web319.TransactionInstruction({
|
|
479
|
+
programId: new import_web319.PublicKey(ix.programAddress ?? ix.programId),
|
|
480
|
+
keys: accounts,
|
|
481
|
+
data: Buffer.from(ix.data ?? [])
|
|
482
|
+
});
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
function getRpc(connection) {
|
|
486
|
+
const endpoint = connection._rpcEndpoint ?? connection.rpcEndpoint;
|
|
487
|
+
if (!endpoint) throw new Error("kit: cannot extract RPC endpoint from connection");
|
|
488
|
+
return (0, import_kit3.createSolanaRpc)(endpoint);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// src/tab/assembleSignV2.ts
|
|
492
|
+
var VAULT_PROGRAM_EXEC_ROLE_ID = 1;
|
|
493
|
+
var USDC_DECIMALS = 6;
|
|
494
|
+
var defaultAssembleSignV2 = async (a) => {
|
|
495
|
+
const rpc = getRpc(a.connection);
|
|
496
|
+
const swig = await (0, import_kit4.fetchSwig)(rpc, (0, import_kit5.address)(a.swigAddress.toBase58()));
|
|
497
|
+
if (!swig) throw new Error(`tab: swig not found on-chain: ${a.swigAddress.toBase58()}`);
|
|
498
|
+
const swigWalletKitAddr = await (0, import_kit4.getSwigWalletAddress)(swig);
|
|
499
|
+
const swigWalletPda = new import_web320.PublicKey(String(swigWalletKitAddr));
|
|
500
|
+
const usdcMint = new import_web320.PublicKey(USDC_MAINNET);
|
|
501
|
+
const sourceAta = (0, import_spl_token.getAssociatedTokenAddressSync)(usdcMint, swigWalletPda, true);
|
|
502
|
+
const transferIxs = a.transfers.map(
|
|
503
|
+
(t) => (0, import_token.getTransferCheckedInstruction)({
|
|
504
|
+
source: (0, import_kit5.address)(sourceAta.toBase58()),
|
|
505
|
+
mint: (0, import_kit5.address)(usdcMint.toBase58()),
|
|
506
|
+
destination: (0, import_kit5.address)(t.destinationAta.toBase58()),
|
|
507
|
+
authority: swigWalletKitAddr,
|
|
508
|
+
amount: t.amount,
|
|
509
|
+
decimals: USDC_DECIMALS
|
|
510
|
+
})
|
|
511
|
+
);
|
|
512
|
+
const signIx = await (0, import_kit4.getSignInstructions)(
|
|
513
|
+
swig,
|
|
514
|
+
VAULT_PROGRAM_EXEC_ROLE_ID,
|
|
515
|
+
transferIxs,
|
|
516
|
+
false,
|
|
517
|
+
{ payer: (0, import_kit5.address)(a.feePayer.toBase58()), preInstructions: [a.vaultIx] }
|
|
518
|
+
);
|
|
519
|
+
return kitInstructionsToWeb3(signIx);
|
|
520
|
+
};
|
|
521
|
+
|
|
522
|
+
// src/tab/settleTab.ts
|
|
523
|
+
var defaultReadPriorSpent = async (connection, vaultPda) => {
|
|
524
|
+
const vault = await readVaultFull(connection, vaultPda);
|
|
525
|
+
const session = vault.activeSession;
|
|
526
|
+
if (!session) throw new Error("settleTab: no active session on vault");
|
|
527
|
+
return session.spent;
|
|
528
|
+
};
|
|
529
|
+
async function settleTab(p) {
|
|
530
|
+
const readPrior = p.readPriorSpent ?? defaultReadPriorSpent;
|
|
531
|
+
const priorSpent = await readPrior(p.connection, p.vaultPda);
|
|
532
|
+
if (p.cumulativeAmount <= priorSpent) {
|
|
533
|
+
throw new Error(
|
|
534
|
+
`settleTab: non-monotonic cumulative \u2014 ${p.cumulativeAmount} <= prior spent ${priorSpent}`
|
|
535
|
+
);
|
|
536
|
+
}
|
|
537
|
+
const delta = p.cumulativeAmount - priorSpent;
|
|
538
|
+
const message = voucherPayloadMessage({
|
|
539
|
+
channelId: p.channelId,
|
|
540
|
+
cumulativeAmount: p.cumulativeAmount,
|
|
541
|
+
sequenceNumber: p.sequenceNumber
|
|
542
|
+
});
|
|
543
|
+
const signature = await p.sessionSigner.sign(message);
|
|
544
|
+
const precompileIx = buildEd25519VerifyInstruction(
|
|
545
|
+
p.sessionSigner.publicKey,
|
|
546
|
+
signature,
|
|
547
|
+
message
|
|
548
|
+
);
|
|
549
|
+
const vaultIx = buildSettleTabVoucherInstruction({
|
|
550
|
+
vaultPda: p.vaultPda,
|
|
551
|
+
swigAddress: p.swigAddress,
|
|
552
|
+
dexterAuthority: p.dexterAuthority,
|
|
553
|
+
channelId: p.channelId,
|
|
554
|
+
cumulativeAmount: p.cumulativeAmount,
|
|
555
|
+
sequenceNumber: p.sequenceNumber
|
|
556
|
+
});
|
|
557
|
+
const assemble = p.assembleSignV2 ?? defaultAssembleSignV2;
|
|
558
|
+
const signV2Ixs = await assemble({
|
|
559
|
+
connection: p.connection,
|
|
560
|
+
swigAddress: p.swigAddress,
|
|
561
|
+
feePayer: p.feePayer,
|
|
562
|
+
vaultIx,
|
|
563
|
+
transfers: [{ destinationAta: p.sellerAta, amount: delta }]
|
|
564
|
+
});
|
|
565
|
+
return [precompileIx, vaultIx, ...signV2Ixs];
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// src/tab/readTabMeter.ts
|
|
569
|
+
async function readTabMeter(connection, vaultPda, read = readVaultFull) {
|
|
570
|
+
const vault = await read(connection, vaultPda);
|
|
571
|
+
const session = vault.activeSession;
|
|
572
|
+
if (!session) throw new Error("readTabMeter: no active session on vault");
|
|
573
|
+
const { spent, maxAmount } = session;
|
|
574
|
+
const raw = maxAmount - spent;
|
|
575
|
+
const remaining = raw > 0n ? raw : 0n;
|
|
576
|
+
return { spent, maxAmount, remaining };
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// src/tab/credit.ts
|
|
580
|
+
async function drawCredit(p) {
|
|
581
|
+
const vaultIx = buildDrawCreditInstruction({
|
|
582
|
+
financierSwig: p.financierSwig,
|
|
583
|
+
vaultPda: p.userVaultPda,
|
|
584
|
+
dexterAuthority: p.dexterAuthority,
|
|
585
|
+
amount: p.amount,
|
|
586
|
+
recoveryWindowSeconds: p.recoveryWindowSeconds
|
|
587
|
+
});
|
|
588
|
+
const assemble = p.assembleSignV2 ?? defaultAssembleSignV2;
|
|
589
|
+
const signV2Ixs = await assemble({
|
|
590
|
+
connection: p.connection,
|
|
591
|
+
swigAddress: p.financierSwig,
|
|
592
|
+
feePayer: p.feePayer,
|
|
593
|
+
vaultIx,
|
|
594
|
+
transfers: [{ destinationAta: p.sellerAta, amount: p.amount }]
|
|
595
|
+
});
|
|
596
|
+
return [vaultIx, ...signV2Ixs];
|
|
597
|
+
}
|
|
598
|
+
async function repayCredit(p) {
|
|
599
|
+
const vaultIx = buildRepayCreditInstruction({
|
|
600
|
+
swigAddress: p.userSwig,
|
|
601
|
+
vaultPda: p.userVaultPda,
|
|
602
|
+
dexterAuthority: p.dexterAuthority,
|
|
603
|
+
amount: p.amount
|
|
604
|
+
});
|
|
605
|
+
const assemble = p.assembleSignV2 ?? defaultAssembleSignV2;
|
|
606
|
+
const signV2Ixs = await assemble({
|
|
607
|
+
connection: p.connection,
|
|
608
|
+
swigAddress: p.userSwig,
|
|
609
|
+
feePayer: p.feePayer,
|
|
610
|
+
vaultIx,
|
|
611
|
+
transfers: [{ destinationAta: p.financierAta, amount: p.amount }]
|
|
612
|
+
});
|
|
613
|
+
return [vaultIx, ...signV2Ixs];
|
|
614
|
+
}
|
|
615
|
+
async function seizeCollateral(p) {
|
|
616
|
+
const vaultIx = buildSeizeCollateralInstruction({
|
|
617
|
+
swigAddress: p.userSwig,
|
|
618
|
+
vaultPda: p.userVaultPda,
|
|
619
|
+
dexterAuthority: p.dexterAuthority
|
|
620
|
+
});
|
|
621
|
+
const assemble = p.assembleSignV2 ?? defaultAssembleSignV2;
|
|
622
|
+
const signV2Ixs = await assemble({
|
|
623
|
+
connection: p.connection,
|
|
624
|
+
swigAddress: p.userSwig,
|
|
625
|
+
feePayer: p.feePayer,
|
|
626
|
+
vaultIx,
|
|
627
|
+
transfers: [{ destinationAta: p.financierAta, amount: p.seizeAmount }]
|
|
628
|
+
});
|
|
629
|
+
return [vaultIx, ...signV2Ixs];
|
|
630
|
+
}
|
|
631
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
632
|
+
0 && (module.exports = {
|
|
633
|
+
defaultAssembleSignV2,
|
|
634
|
+
drawCredit,
|
|
635
|
+
openTab,
|
|
636
|
+
readTabMeter,
|
|
637
|
+
repayCredit,
|
|
638
|
+
seizeCollateral,
|
|
639
|
+
settleTab
|
|
640
|
+
});
|