@ercworldio/blockchain-shared 1.0.5-dev.7-PROJ-1469.9 → 1.0.5-dev.7-PROJ-1469.10

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.
@@ -6,6 +6,12 @@ import { ChainId } from "../../../interfaces";
6
6
  interface AdditionalConstructorParams {
7
7
  signer_keypair?: Keypair;
8
8
  localnet: boolean;
9
+ /**
10
+ * Address Lookup Table holding the batch path's static accounts. Supply it to send v0
11
+ * transactions, which is required for batches carrying more than two treasury signatures.
12
+ * Create it once with `create_lookup_table` and persist the returned address.
13
+ */
14
+ lookup_table_address?: string;
9
15
  }
10
16
  declare class SolanaEscrowAdmin {
11
17
  provider: anchor.AnchorProvider;
@@ -83,6 +89,18 @@ declare class SolanaEscrowAdmin {
83
89
  */
84
90
  set_pause_state: (target_state: boolean) => Promise<string>;
85
91
  withdraw_batch: (chain_id: ChainId, token_address: string, receivers: BatchReceiver[]) => Promise<string>;
92
+ /**
93
+ * Idempotently ensures the batch path's Address Lookup Table exists and covers `mints`.
94
+ * Safe to call on every startup: it discovers an existing table on-chain, extends it when
95
+ * addresses are missing, and only creates one when none exists. Returns the address, or null
96
+ * when provisioning failed (callers then run on legacy transactions).
97
+ *
98
+ * `withdraw_batch` calls this automatically for signature-carrying batches, so wiring it into
99
+ * startup is about observability and warming, not correctness.
100
+ */
101
+ ensure_lookup_table: (mints: string[]) => Promise<string | null>;
102
+ /** @deprecated prefer `ensure_lookup_table` — this throws instead of degrading gracefully. */
103
+ create_lookup_table: (mints: string[]) => Promise<string>;
86
104
  /**
87
105
  *
88
106
  * @param token_address Address of the token to withdraw
@@ -1 +1 @@
1
- {"version":3,"file":"SolanaEscrowAdmin.d.ts","sourceRoot":"","sources":["../../../../src/services/solana/escrow/SolanaEscrowAdmin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAqC,MAAM,iBAAiB,CAAC;AAEpG,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAE5C,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,OAAO,EAAE,aAAa,EAAE,4BAA4B,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACtG,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAkB9C,UAAU,2BAA2B;IACjC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;CACrB;AAED,cAAM,iBAAiB;IACZ,QAAQ,EAAE,MAAM,CAAC,cAAc,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,MAAM,CAAC,CAAU;IAClB,UAAU,EAAE,UAAU,CAAC;gBAG1B,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,SAAS,EAC1B,eAAe,EAAE,wBAAwB,EACzC,mBAAmB,EAAE,4BAA4B,EACjD,OAAO,EAAE,MAAM,EACf,gBAAgB,CAAC,EAAE,2BAA2B,EAC9C,UAAU,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU;IAkCvC;;;OAGG;IACH,OAAO,CAAC,OAAO,CAGb;IAEF;;;OAGG;IACI,kBAAkB,wBAGvB;IAKF;;;OAGG;IACI,SAAS,yBAEf;IAED;;;;OAIG;IACI,QAAQ,GAAU,gBAAgB,MAAM,sBAE9C;IAED;;;;OAIG;IACI,gBAAgB,GAAU,eAAe,MAAM,sBAErD;IAEM,YAAY,oCAElB;IAGD;;;OAGG;IACI,kBAAkB,0BAExB;IAED;;;OAGG;IACI,UAAU,0BAEhB;IAED;;;;OAIG;IACI,iBAAiB,GAAU,eAAe,MAAM,qBAEtD;IAED;;;;OAIG;IACI,oBAAoB,GAAU,eAAe,MAAM,qBAEzD;IAED;;;;OAIG;IACI,SAAS,GAAU,gBAAgB,MAAM,qBAE/C;IAGD;;;;OAIG;IACI,YAAY,GAAU,gBAAgB,MAAM,qBAElD;IAED;;;;OAIG;IACI,eAAe,GAAU,cAAc,OAAO,qBAEpD;IAIM,cAAc,GAAU,UAAU,OAAO,EAAE,eAAe,MAAM,EAAE,WAAW,aAAa,EAAE,qBAElG;IAGD;;;;;;OAMG;IACI,QAAQ,GAAU,eAAe,MAAM,EAAE,oBAAoB,MAAM,EAAE,kBAAkB,MAAM,iCAEnG;IAED;;;;;OAKG;IACI,OAAO,GAAU,eAAe,MAAM,EAAE,oBAAoB,MAAM,qBAExE;CAKJ;AAED,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"SolanaEscrowAdmin.d.ts","sourceRoot":"","sources":["../../../../src/services/solana/escrow/SolanaEscrowAdmin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAqC,MAAM,iBAAiB,CAAC;AAEpG,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAE5C,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,OAAO,EAAE,aAAa,EAAE,4BAA4B,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACtG,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAkB9C,UAAU,2BAA2B;IACjC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,cAAM,iBAAiB;IACZ,QAAQ,EAAE,MAAM,CAAC,cAAc,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,MAAM,CAAC,CAAU;IAClB,UAAU,EAAE,UAAU,CAAC;gBAG1B,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,SAAS,EAC1B,eAAe,EAAE,wBAAwB,EACzC,mBAAmB,EAAE,4BAA4B,EACjD,OAAO,EAAE,MAAM,EACf,gBAAgB,CAAC,EAAE,2BAA2B,EAC9C,UAAU,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU;IAkCvC;;;OAGG;IACH,OAAO,CAAC,OAAO,CAGb;IAEF;;;OAGG;IACI,kBAAkB,wBAGvB;IAKF;;;OAGG;IACI,SAAS,yBAEf;IAED;;;;OAIG;IACI,QAAQ,GAAU,gBAAgB,MAAM,sBAE9C;IAED;;;;OAIG;IACI,gBAAgB,GAAU,eAAe,MAAM,sBAErD;IAEM,YAAY,oCAElB;IAGD;;;OAGG;IACI,kBAAkB,0BAExB;IAED;;;OAGG;IACI,UAAU,0BAEhB;IAED;;;;OAIG;IACI,iBAAiB,GAAU,eAAe,MAAM,qBAEtD;IAED;;;;OAIG;IACI,oBAAoB,GAAU,eAAe,MAAM,qBAEzD;IAED;;;;OAIG;IACI,SAAS,GAAU,gBAAgB,MAAM,qBAE/C;IAGD;;;;OAIG;IACI,YAAY,GAAU,gBAAgB,MAAM,qBAElD;IAED;;;;OAIG;IACI,eAAe,GAAU,cAAc,OAAO,qBAEpD;IAIM,cAAc,GAAU,UAAU,OAAO,EAAE,eAAe,MAAM,EAAE,WAAW,aAAa,EAAE,qBAElG;IAED;;;;;;;;OAQG;IACI,mBAAmB,GAAU,OAAO,MAAM,EAAE,4BAGlD;IAED,8FAA8F;IACvF,mBAAmB,GAAU,OAAO,MAAM,EAAE,qBAElD;IAGD;;;;;;OAMG;IACI,QAAQ,GAAU,eAAe,MAAM,EAAE,oBAAoB,MAAM,EAAE,kBAAkB,MAAM,iCAEnG;IAED;;;;;OAKG;IACI,OAAO,GAAU,eAAe,MAAM,EAAE,oBAAoB,MAAM,qBAExE;CAKJ;AAED,eAAe,iBAAiB,CAAC"}
@@ -165,6 +165,23 @@ class SolanaEscrowAdmin {
165
165
  this.withdraw_batch = (chain_id, token_address, receivers) => __awaiter(this, void 0, void 0, function* () {
166
166
  return this.adminUtility.withdraw_batch(chain_id, token_address, receivers, this.signer);
167
167
  });
168
+ /**
169
+ * Idempotently ensures the batch path's Address Lookup Table exists and covers `mints`.
170
+ * Safe to call on every startup: it discovers an existing table on-chain, extends it when
171
+ * addresses are missing, and only creates one when none exists. Returns the address, or null
172
+ * when provisioning failed (callers then run on legacy transactions).
173
+ *
174
+ * `withdraw_batch` calls this automatically for signature-carrying batches, so wiring it into
175
+ * startup is about observability and warming, not correctness.
176
+ */
177
+ this.ensure_lookup_table = (mints) => __awaiter(this, void 0, void 0, function* () {
178
+ const table = yield this.adminUtility.ensure_lookup_table(mints, this.signer);
179
+ return table ? table.toBase58() : null;
180
+ });
181
+ /** @deprecated prefer `ensure_lookup_table` — this throws instead of degrading gracefully. */
182
+ this.create_lookup_table = (mints) => __awaiter(this, void 0, void 0, function* () {
183
+ return this.adminUtility.create_lookup_table(mints, this.signer);
184
+ });
168
185
  /**
169
186
  *
170
187
  * @param token_address Address of the token to withdraw
@@ -205,7 +222,7 @@ class SolanaEscrowAdmin {
205
222
  const program = new anchor.Program(target_idl, provider);
206
223
  this.program = program;
207
224
  this.provider = provider;
208
- this.adminUtility = EscrowAdminUtility_1.default.createWithCustomProgramId(provider, new web3_js_1.PublicKey(escrowAddress), this.get_idl());
225
+ this.adminUtility = EscrowAdminUtility_1.default.createWithCustomProgramId(provider, new web3_js_1.PublicKey(escrowAddress), this.get_idl(), additionalParams === null || additionalParams === void 0 ? void 0 : additionalParams.lookup_table_address);
209
226
  if (additionalParams === null || additionalParams === void 0 ? void 0 : additionalParams.signer_keypair)
210
227
  this.signer = additionalParams.signer_keypair;
211
228
  }
@@ -7,7 +7,43 @@ import { ChainId } from "../../../../interfaces";
7
7
  export declare class EscrowAdminUtility {
8
8
  program: Program<Escrow>;
9
9
  provider: anchor.AnchorProvider;
10
- constructor(program: Program<Escrow>, provider: anchor.AnchorProvider);
10
+ /**
11
+ * Optional Address Lookup Table. When set, transactions are sent as v0 and the batch path's
12
+ * ~11 static accounts collapse from 32 bytes each to a 1-byte index — roughly 300 bytes back,
13
+ * which is what makes >2 treasury signatures fit under the 1232-byte limit.
14
+ */
15
+ private lookupTableAddress?;
16
+ private lookupTableCache?;
17
+ constructor(program: Program<Escrow>, provider: anchor.AnchorProvider, lookupTableAddress?: string);
18
+ /** Accounts that are identical on every batch withdrawal — the ALT payload. */
19
+ lookup_table_addresses(mints: string[]): PublicKey[];
20
+ /**
21
+ * Idempotently guarantees a lookup table covering `mints` exists and is usable.
22
+ *
23
+ * Deliberately keeps no external state: tables are discovered on-chain by their authority
24
+ * (the funding wallet), so there is nothing to persist, migrate, or keep in sync across
25
+ * environments and worker instances. Extends a table that is missing addresses, creates one
26
+ * when none exists, and returns the usable address.
27
+ *
28
+ * Returns null if provisioning fails — the lookup table is an optimisation, so callers fall
29
+ * back to legacy transactions rather than failing a withdrawal that would otherwise succeed.
30
+ */
31
+ ensure_lookup_table(mints: string[], signer?: Keypair): Promise<PublicKey | null>;
32
+ /** Back-compat wrapper for explicit one-time provisioning; prefer `ensure_lookup_table`. */
33
+ create_lookup_table(mints: string[], signer?: Keypair): Promise<string>;
34
+ private fetchLookupTable;
35
+ /**
36
+ * Finds a live table already owned by this authority. `getProgramAccounts` is filtered
37
+ * server-side on the authority pubkey, which sits at a fixed offset in the table header:
38
+ * u32 typeIndex + u64 deactivationSlot + u64 lastExtendedSlot + u8 startIndex + u8 option tag.
39
+ */
40
+ private discoverLookupTable;
41
+ private missingAddresses;
42
+ private createLookupTable;
43
+ private extendLookupTable;
44
+ private waitForLookupTableActivation;
45
+ /** Resolves (and caches) the configured lookup table; [] when none is set or it's missing. */
46
+ private resolveLookupTables;
11
47
  /**
12
48
  * Check if the escrow program is paused or running
13
49
  * @returns true/false. True: program is paused. False: Program is running
@@ -111,6 +147,8 @@ export declare class EscrowAdminUtility {
111
147
  getVaultBalance(): Promise<number>;
112
148
  getVaultTokenBalance(mint: PublicKey): Promise<number>;
113
149
  private sendTransaction;
150
+ private sendVersionedTransaction;
151
+ private sendLegacyTransaction;
114
152
  confirmTransaction(signature: string, commitment?: Commitment): Promise<void>;
115
153
  waitForConfirmation(signature: TransactionSignature, commitment?: 'confirmed' | 'finalized', timeoutMs?: number): Promise<void>;
116
154
  /**
@@ -127,7 +165,7 @@ export declare class EscrowAdminUtility {
127
165
  * @param idl IDL file - Escrow program idl
128
166
  * @returns
129
167
  */
130
- static createWithCustomProgramId(provider: anchor.AnchorProvider, programId: PublicKey, idl: anchor.Idl): EscrowAdminUtility;
168
+ static createWithCustomProgramId(provider: anchor.AnchorProvider, programId: PublicKey, idl: anchor.Idl, lookupTableAddress?: string): EscrowAdminUtility;
131
169
  }
132
170
  export default EscrowAdminUtility;
133
171
  //# sourceMappingURL=EscrowAdminUtility.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EscrowAdminUtility.d.ts","sourceRoot":"","sources":["../../../../../src/services/solana/escrow/services/EscrowAdminUtility.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EscrowAdminUtility.d.ts","sourceRoot":"","sources":["../../../../../src/services/solana/escrow/services/EscrowAdminUtility.ts"],"names":[],"mappings":"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"}
@@ -58,9 +58,181 @@ const TokenAccountService_1 = require("./TokenAccountService");
58
58
  const SolanaTokenProgramCache_1 = require("./SolanaTokenProgramCache");
59
59
  const TreasuryWithdrawalSignature_1 = require("./TreasuryWithdrawalSignature");
60
60
  class EscrowAdminUtility {
61
- constructor(program, provider) {
61
+ constructor(program, provider, lookupTableAddress) {
62
62
  this.program = program;
63
63
  this.provider = provider;
64
+ if (lookupTableAddress)
65
+ this.lookupTableAddress = new web3_js_1.PublicKey(lookupTableAddress);
66
+ }
67
+ /** Accounts that are identical on every batch withdrawal — the ALT payload. */
68
+ lookup_table_addresses(mints) {
69
+ const programId = this.program.programId;
70
+ const global = [
71
+ EscrowService.findEscrowConfigPda(programId),
72
+ EscrowService.findVaultAuthorityPda(programId),
73
+ web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("treasury-config")], programId)[0],
74
+ web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("timelock-config")], programId)[0],
75
+ spl_token_1.TOKEN_PROGRAM_ID,
76
+ web3_js_1.SystemProgram.programId,
77
+ web3_js_1.SYSVAR_INSTRUCTIONS_PUBKEY,
78
+ ];
79
+ const perMint = mints.flatMap(m => {
80
+ const mint = new web3_js_1.PublicKey(m);
81
+ return [
82
+ mint,
83
+ EscrowService.findVaultAta(mint, programId),
84
+ web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("token-threshold"), mint.toBytes()], programId)[0],
85
+ web3_js_1.PublicKey.findProgramAddressSync([Buffer.from("token-timelock"), mint.toBytes()], programId)[0],
86
+ ];
87
+ });
88
+ return [...global, ...perMint];
89
+ }
90
+ /**
91
+ * Idempotently guarantees a lookup table covering `mints` exists and is usable.
92
+ *
93
+ * Deliberately keeps no external state: tables are discovered on-chain by their authority
94
+ * (the funding wallet), so there is nothing to persist, migrate, or keep in sync across
95
+ * environments and worker instances. Extends a table that is missing addresses, creates one
96
+ * when none exists, and returns the usable address.
97
+ *
98
+ * Returns null if provisioning fails — the lookup table is an optimisation, so callers fall
99
+ * back to legacy transactions rather than failing a withdrawal that would otherwise succeed.
100
+ */
101
+ ensure_lookup_table(mints, signer) {
102
+ return __awaiter(this, void 0, void 0, function* () {
103
+ try {
104
+ const required = this.lookup_table_addresses(mints);
105
+ const existing = this.lookupTableAddress
106
+ ? yield this.fetchLookupTable(this.lookupTableAddress)
107
+ : yield this.discoverLookupTable();
108
+ if (existing) {
109
+ const missing = this.missingAddresses(existing.state.addresses, required);
110
+ if (missing.length)
111
+ yield this.extendLookupTable(existing.key, missing, signer);
112
+ this.lookupTableAddress = existing.key;
113
+ this.lookupTableCache = undefined;
114
+ return existing.key;
115
+ }
116
+ const table = yield this.createLookupTable(required, signer);
117
+ this.lookupTableAddress = table;
118
+ this.lookupTableCache = undefined;
119
+ return table;
120
+ }
121
+ catch (error) {
122
+ return null;
123
+ }
124
+ });
125
+ }
126
+ /** Back-compat wrapper for explicit one-time provisioning; prefer `ensure_lookup_table`. */
127
+ create_lookup_table(mints, signer) {
128
+ return __awaiter(this, void 0, void 0, function* () {
129
+ const table = yield this.ensure_lookup_table(mints, signer);
130
+ if (!table)
131
+ throw new Error("Failed to provision the escrow lookup table");
132
+ return table.toBase58();
133
+ });
134
+ }
135
+ fetchLookupTable(key) {
136
+ return __awaiter(this, void 0, void 0, function* () {
137
+ const { value } = yield this.provider.connection.getAddressLookupTable(key);
138
+ return value ? { key, state: value.state } : null;
139
+ });
140
+ }
141
+ /**
142
+ * Finds a live table already owned by this authority. `getProgramAccounts` is filtered
143
+ * server-side on the authority pubkey, which sits at a fixed offset in the table header:
144
+ * u32 typeIndex + u64 deactivationSlot + u64 lastExtendedSlot + u8 startIndex + u8 option tag.
145
+ */
146
+ discoverLookupTable() {
147
+ return __awaiter(this, void 0, void 0, function* () {
148
+ const AUTHORITY_OFFSET = 22;
149
+ const authority = this.provider.wallet.publicKey;
150
+ const accounts = yield this.provider.connection.getProgramAccounts(web3_js_1.AddressLookupTableProgram.programId, { filters: [{ memcmp: { offset: AUTHORITY_OFFSET, bytes: authority.toBase58() } }] });
151
+ const live = accounts
152
+ .map(a => {
153
+ try {
154
+ return { key: a.pubkey, state: web3_js_1.AddressLookupTableAccount.deserialize(a.account.data) };
155
+ }
156
+ catch (_a) {
157
+ return null;
158
+ }
159
+ })
160
+ .filter((t) => t !== null)
161
+ // A deactivated table cannot be used; MAX u64 means "never deactivated".
162
+ .filter(t => t.state.deactivationSlot === BigInt("18446744073709551615"));
163
+ if (!live.length)
164
+ return null;
165
+ // Prefer the most complete table so repeated runs converge on one.
166
+ return live.sort((a, b) => b.state.addresses.length - a.state.addresses.length)[0];
167
+ });
168
+ }
169
+ missingAddresses(present, required) {
170
+ const have = new Set(present.map(a => a.toBase58()));
171
+ const seen = new Set();
172
+ return required.filter(a => {
173
+ const k = a.toBase58();
174
+ if (have.has(k) || seen.has(k))
175
+ return false;
176
+ seen.add(k);
177
+ return true;
178
+ });
179
+ }
180
+ createLookupTable(addresses, signer) {
181
+ return __awaiter(this, void 0, void 0, function* () {
182
+ const authority = this.provider.wallet.publicKey;
183
+ const slot = yield this.provider.connection.getSlot("finalized");
184
+ const [createIx, table] = web3_js_1.AddressLookupTableProgram.createLookupTable({
185
+ authority, payer: authority, recentSlot: slot,
186
+ });
187
+ yield this.sendLegacyTransaction([createIx], signer);
188
+ yield this.extendLookupTable(table, addresses, signer);
189
+ return table;
190
+ });
191
+ }
192
+ extendLookupTable(table, addresses, signer) {
193
+ return __awaiter(this, void 0, void 0, function* () {
194
+ const authority = this.provider.wallet.publicKey;
195
+ // Chunked so the extend instruction itself stays under the transaction size limit.
196
+ for (let i = 0; i < addresses.length; i += 20) {
197
+ yield this.sendLegacyTransaction([
198
+ web3_js_1.AddressLookupTableProgram.extendLookupTable({
199
+ payer: authority, authority, lookupTable: table, addresses: addresses.slice(i, i + 20),
200
+ }),
201
+ ], signer);
202
+ }
203
+ // A table is only usable from the slot after it was written; wait so the first v0
204
+ // transaction referencing it can actually resolve the accounts.
205
+ yield this.waitForLookupTableActivation(table);
206
+ });
207
+ }
208
+ waitForLookupTableActivation(table_1) {
209
+ return __awaiter(this, arguments, void 0, function* (table, timeoutMs = 30000) {
210
+ const startSlot = yield this.provider.connection.getSlot("confirmed");
211
+ const deadline = Date.now() + timeoutMs;
212
+ while (Date.now() < deadline) {
213
+ const [{ value }, slot] = yield Promise.all([
214
+ this.provider.connection.getAddressLookupTable(table),
215
+ this.provider.connection.getSlot("confirmed"),
216
+ ]);
217
+ if (value && slot > startSlot)
218
+ return;
219
+ yield new Promise(r => setTimeout(r, 1000));
220
+ }
221
+ });
222
+ }
223
+ /** Resolves (and caches) the configured lookup table; [] when none is set or it's missing. */
224
+ resolveLookupTables() {
225
+ return __awaiter(this, void 0, void 0, function* () {
226
+ if (!this.lookupTableAddress)
227
+ return [];
228
+ if (this.lookupTableCache)
229
+ return [this.lookupTableCache];
230
+ const { value } = yield this.provider.connection.getAddressLookupTable(this.lookupTableAddress);
231
+ if (!value)
232
+ return [];
233
+ this.lookupTableCache = value;
234
+ return [value];
235
+ });
64
236
  }
65
237
  // ==========================
66
238
  // Admin View Methods
@@ -368,6 +540,13 @@ class EscrowAdminUtility {
368
540
  withdraw_batch(chain_id, token_address, recipients, signer) {
369
541
  return __awaiter(this, void 0, void 0, function* () {
370
542
  const token_pubkey = new web3_js_1.PublicKey(token_address);
543
+ // A batch carrying treasury signatures only fits in 1232 bytes as a v0 transaction, so make
544
+ // sure the lookup table exists before building it. This is idempotent and self-healing: the
545
+ // first signature-gated withdrawal provisions the table, every later one reuses it, and a
546
+ // failure here simply leaves us on legacy transactions rather than blocking the withdrawal.
547
+ if (recipients.some(r => { var _a; return (_a = r.signatures) === null || _a === void 0 ? void 0 : _a.length; })) {
548
+ yield this.ensure_lookup_table([token_address], signer);
549
+ }
371
550
  switch (token_pubkey.toBase58()) {
372
551
  case (web3_js_1.SystemProgram.programId.toBase58()):
373
552
  return this.batch_withdraw_sol(chain_id, recipients, signer);
@@ -623,29 +802,59 @@ class EscrowAdminUtility {
623
802
  sendTransaction(ixs, signer) {
624
803
  return __awaiter(this, void 0, void 0, function* () {
625
804
  try {
626
- const tx = new web3_js_1.Transaction();
627
- for (let ix of ixs) {
628
- tx.add(ix);
629
- }
630
- tx.feePayer = this.provider.wallet.publicKey;
631
- tx.recentBlockhash = (yield this.provider.connection.getLatestBlockhash()).blockhash;
632
- let signature = "";
633
- if (signer) {
634
- tx.sign(signer);
635
- signature = yield this.provider.connection.sendRawTransaction(tx.serialize());
636
- yield (0, TransactionsService_1.waitForTransactionConfirmation)(this.provider, signature, "confirmed");
805
+ // Prefer a v0 transaction when a lookup table is configured — it is the only way a
806
+ // batch carrying more than two treasury signatures fits in 1232 bytes.
807
+ const lookupTables = yield this.resolveLookupTables();
808
+ if (lookupTables.length) {
809
+ return yield this.sendVersionedTransaction(ixs, lookupTables, signer);
637
810
  }
638
- else {
639
- signature = yield this.provider.sendAndConfirm(tx);
640
- yield (0, TransactionsService_1.waitForTransactionConfirmation)(this.provider, signature, "confirmed");
641
- }
642
- return signature;
811
+ return yield this.sendLegacyTransaction(ixs, signer);
643
812
  }
644
813
  catch (error) {
645
814
  throw Errors_1.default.decode(error);
646
815
  }
647
816
  });
648
817
  }
818
+ sendVersionedTransaction(ixs, lookupTables, signer) {
819
+ return __awaiter(this, void 0, void 0, function* () {
820
+ const message = new web3_js_1.TransactionMessage({
821
+ payerKey: this.provider.wallet.publicKey,
822
+ recentBlockhash: (yield this.provider.connection.getLatestBlockhash()).blockhash,
823
+ instructions: ixs,
824
+ }).compileToV0Message(lookupTables);
825
+ const tx = new web3_js_1.VersionedTransaction(message);
826
+ if (signer) {
827
+ tx.sign([signer]);
828
+ }
829
+ else {
830
+ yield this.provider.wallet.signTransaction(tx);
831
+ }
832
+ const signature = yield this.provider.connection.sendRawTransaction(tx.serialize());
833
+ yield (0, TransactionsService_1.waitForTransactionConfirmation)(this.provider, signature, "confirmed");
834
+ return signature;
835
+ });
836
+ }
837
+ sendLegacyTransaction(ixs, signer) {
838
+ return __awaiter(this, void 0, void 0, function* () {
839
+ const tx = new web3_js_1.Transaction();
840
+ for (let ix of ixs) {
841
+ tx.add(ix);
842
+ }
843
+ tx.feePayer = this.provider.wallet.publicKey;
844
+ tx.recentBlockhash = (yield this.provider.connection.getLatestBlockhash()).blockhash;
845
+ let signature = "";
846
+ if (signer) {
847
+ tx.sign(signer);
848
+ signature = yield this.provider.connection.sendRawTransaction(tx.serialize());
849
+ yield (0, TransactionsService_1.waitForTransactionConfirmation)(this.provider, signature, "confirmed");
850
+ }
851
+ else {
852
+ signature = yield this.provider.sendAndConfirm(tx);
853
+ yield (0, TransactionsService_1.waitForTransactionConfirmation)(this.provider, signature, "confirmed");
854
+ }
855
+ return signature;
856
+ });
857
+ }
649
858
  confirmTransaction(signature_1) {
650
859
  return __awaiter(this, arguments, void 0, function* (signature, commitment = "finalized") {
651
860
  yield this.provider.connection.confirmTransaction(signature, commitment);
@@ -698,11 +907,11 @@ class EscrowAdminUtility {
698
907
  * @param idl IDL file - Escrow program idl
699
908
  * @returns
700
909
  */
701
- static createWithCustomProgramId(provider, programId, idl) {
910
+ static createWithCustomProgramId(provider, programId, idl, lookupTableAddress) {
702
911
  // Override the program ID in the IDL
703
912
  const modifiedIdl = Object.assign(Object.assign({}, idl), { address: programId.toBase58() });
704
913
  const program = new anchor_1.Program(modifiedIdl, provider);
705
- return new EscrowAdminUtility(program, provider);
914
+ return new EscrowAdminUtility(program, provider, lookupTableAddress);
706
915
  }
707
916
  }
708
917
  exports.EscrowAdminUtility = EscrowAdminUtility;
@@ -48,6 +48,11 @@ export interface Ed25519Entry {
48
48
  * (each entry's pubkey, signature and message live in this instruction's own data). This is the
49
49
  * compact layout the program scans in `verify_treasury_threshold`; one instruction for the whole
50
50
  * batch keeps the transaction far smaller than one instruction per signature.
51
+ *
52
+ * Identical messages are stored ONCE and shared by every signature over them, since the offsets
53
+ * table lets multiple entries point at the same message region. This matters: the N signers who
54
+ * approve one withdrawal all sign the same ~194-byte payload, so without sharing, a 2-of-N
55
+ * approval would spend an extra ~194 bytes and overflow Solana's 1232-byte transaction limit.
51
56
  */
52
57
  export declare function buildTreasuryEd25519Instruction(entries: Ed25519Entry[]): TransactionInstruction;
53
58
  //# sourceMappingURL=TreasuryWithdrawalSignature.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TreasuryWithdrawalSignature.d.ts","sourceRoot":"","sources":["../../../../../src/services/solana/escrow/services/TreasuryWithdrawalSignature.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,SAAS,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAGpF;;;;;GAKG;AAEH,wEAAwE;AACxE,MAAM,WAAW,sBAAsB;IACnC,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE;IACnD,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,CAUT;AAED,oFAAoF;AACpF,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,CAU5D;AAED,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IACzB,SAAS,EAAE,UAAU,CAAC;IACtB,SAAS,EAAE,UAAU,CAAC;IACtB,OAAO,EAAE,UAAU,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,sBAAsB,CAmC/F"}
1
+ {"version":3,"file":"TreasuryWithdrawalSignature.d.ts","sourceRoot":"","sources":["../../../../../src/services/solana/escrow/services/TreasuryWithdrawalSignature.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,SAAS,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAGpF;;;;;GAKG;AAEH,wEAAwE;AACxE,MAAM,WAAW,sBAAsB;IACnC,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE;IACnD,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,CAUT;AAED,oFAAoF;AACpF,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,CAU5D;AAED,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IACzB,SAAS,EAAE,UAAU,CAAC;IACtB,SAAS,EAAE,UAAU,CAAC;IACtB,OAAO,EAAE,UAAU,CAAC;CACvB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,sBAAsB,CAoD/F"}
@@ -55,6 +55,11 @@ function decodeEd25519Signature(s) {
55
55
  * (each entry's pubkey, signature and message live in this instruction's own data). This is the
56
56
  * compact layout the program scans in `verify_treasury_threshold`; one instruction for the whole
57
57
  * batch keeps the transaction far smaller than one instruction per signature.
58
+ *
59
+ * Identical messages are stored ONCE and shared by every signature over them, since the offsets
60
+ * table lets multiple entries point at the same message region. This matters: the N signers who
61
+ * approve one withdrawal all sign the same ~194-byte payload, so without sharing, a 2-of-N
62
+ * approval would spend an extra ~194 bytes and overflow Solana's 1232-byte transaction limit.
58
63
  */
59
64
  function buildTreasuryEd25519Instruction(entries) {
60
65
  const N = entries.length;
@@ -62,28 +67,43 @@ function buildTreasuryEd25519Instruction(entries) {
62
67
  const ENTRY_SIZE = 32 + 64; // pubkey + signature
63
68
  const header = 2 + N * OFFSETS_SIZE;
64
69
  const msgStart = header + N * ENTRY_SIZE;
65
- const totalMsg = entries.reduce((s, e) => s + e.message.length, 0);
66
- const data = Buffer.alloc(msgStart + totalMsg);
70
+ // Deduplicate message blobs by content; remember where each unique one lands.
71
+ const uniqueMessages = [];
72
+ const messageOffsets = [];
73
+ const seen = new Map();
74
+ let cursor = msgStart;
75
+ for (const entry of entries) {
76
+ const key = Buffer.from(entry.message).toString("base64");
77
+ let offset = seen.get(key);
78
+ if (offset === undefined) {
79
+ offset = cursor;
80
+ seen.set(key, offset);
81
+ uniqueMessages.push(entry.message);
82
+ cursor += entry.message.length;
83
+ }
84
+ messageOffsets.push(offset);
85
+ }
86
+ const data = Buffer.alloc(cursor);
67
87
  data[0] = N; // number of signatures
68
88
  data[1] = 0; // padding
69
- let msgCursor = msgStart;
70
89
  for (let i = 0; i < N; i++) {
71
90
  const base = 2 + i * OFFSETS_SIZE;
72
91
  const pkOffset = header + i * ENTRY_SIZE;
73
92
  const sigOffset = pkOffset + 32;
74
- const msgOffset = msgCursor;
75
- const msgLen = entries[i].message.length;
76
93
  data.writeUInt16LE(sigOffset, base + 0); // signature_offset
77
94
  data.writeUInt16LE(0xffff, base + 2); // signature_instruction_index (self)
78
95
  data.writeUInt16LE(pkOffset, base + 4); // public_key_offset
79
96
  data.writeUInt16LE(0xffff, base + 6); // public_key_instruction_index (self)
80
- data.writeUInt16LE(msgOffset, base + 8); // message_data_offset
81
- data.writeUInt16LE(msgLen, base + 10); // message_data_size
97
+ data.writeUInt16LE(messageOffsets[i], base + 8); // message_data_offset (may be shared)
98
+ data.writeUInt16LE(entries[i].message.length, base + 10); // message_data_size
82
99
  data.writeUInt16LE(0xffff, base + 12); // message_instruction_index (self)
83
100
  data.set(entries[i].publicKey, pkOffset);
84
101
  data.set(entries[i].signature, sigOffset);
85
- data.set(entries[i].message, msgOffset);
86
- msgCursor += msgLen;
102
+ }
103
+ // Write each unique message once, at the offset its first referrer recorded.
104
+ for (let i = 0, offset = msgStart; i < uniqueMessages.length; i++) {
105
+ data.set(uniqueMessages[i], offset);
106
+ offset += uniqueMessages[i].length;
87
107
  }
88
108
  return new web3_js_1.TransactionInstruction({ keys: [], programId: web3_js_1.Ed25519Program.programId, data });
89
109
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ercworldio/blockchain-shared",
3
- "version": "1.0.5-dev.7-PROJ-1469.9",
3
+ "version": "1.0.5-dev.7-PROJ-1469.10",
4
4
  "description": "Shared library for blockchain projects",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",