alkanesjs 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.browser.mjs +180 -8
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.d.ts +35 -1
- package/dist/index.js +178 -7
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -137,6 +137,25 @@ interface RpcCall<T> {
|
|
|
137
137
|
}
|
|
138
138
|
declare function buildRpcCall<T, E = unknown>(method: string, params: unknown[] | undefined, url: string): RpcCall<T>;
|
|
139
139
|
|
|
140
|
+
declare class WaitPacer {
|
|
141
|
+
private maxPerInterval;
|
|
142
|
+
private intervalMs;
|
|
143
|
+
private minGapMs;
|
|
144
|
+
private starts;
|
|
145
|
+
private lastStart;
|
|
146
|
+
private tail;
|
|
147
|
+
constructor(opts: {
|
|
148
|
+
maxPerInterval: number;
|
|
149
|
+
intervalMs: number;
|
|
150
|
+
});
|
|
151
|
+
setRate(maxPerInterval: number, intervalMs: number): void;
|
|
152
|
+
private now;
|
|
153
|
+
private sleep;
|
|
154
|
+
private pruneWindow;
|
|
155
|
+
/** Await this immediately before the call that could rate-limit */
|
|
156
|
+
waitForPacer(): Promise<void>;
|
|
157
|
+
}
|
|
158
|
+
|
|
140
159
|
interface ProviderConfig {
|
|
141
160
|
sandshrewUrl: string;
|
|
142
161
|
electrumApiUrl: string;
|
|
@@ -144,10 +163,15 @@ interface ProviderConfig {
|
|
|
144
163
|
explorerUrl: string;
|
|
145
164
|
defaultFeeRate?: number;
|
|
146
165
|
btcTicker?: string;
|
|
166
|
+
pacerSettings?: PacerSettings;
|
|
147
167
|
}
|
|
148
168
|
declare enum AlkanesPollError {
|
|
149
169
|
UnknownError = "UnknownError"
|
|
150
170
|
}
|
|
171
|
+
type PacerSettings = {
|
|
172
|
+
intervalMs: number;
|
|
173
|
+
maxPerInterval: number;
|
|
174
|
+
};
|
|
151
175
|
type AlkanesParsedTraceResult = {
|
|
152
176
|
create?: AlkanesTraceCreateEvent["data"];
|
|
153
177
|
invoke?: AlkanesTraceInvokeEvent["data"];
|
|
@@ -158,11 +182,14 @@ declare class Provider {
|
|
|
158
182
|
readonly electrumApiUrl: string;
|
|
159
183
|
readonly network: Network;
|
|
160
184
|
readonly explorerUrl: string;
|
|
185
|
+
readonly pacerSettings: PacerSettings;
|
|
161
186
|
readonly btcTicker: string;
|
|
187
|
+
readonly jitterMs = 1000;
|
|
162
188
|
readonly rpc: BaseRpcProvider;
|
|
163
189
|
readonly defaultFeeRate: number;
|
|
164
190
|
private readonly TIMEOUT_MS;
|
|
165
191
|
private readonly INTERVAL_MS;
|
|
192
|
+
pacer: WaitPacer;
|
|
166
193
|
constructor(config: ProviderConfig);
|
|
167
194
|
protected txUrl(txid: string): string;
|
|
168
195
|
protected addressUrl(address: string): string;
|
|
@@ -186,6 +213,9 @@ declare class ElectrumApiProvider {
|
|
|
186
213
|
esplora_broadcastTx(rawTransactionHex: string, customElectrumUrl?: string): Promise<BoxedResponse<string, EsploraFetchError>>;
|
|
187
214
|
esplora_getaddresstxs(address: string, lastSeenTransactionId?: string): Promise<BoxedResponse<IEsploraTransaction[], EsploraFetchError>>;
|
|
188
215
|
esplora_getbulktransactions(transactionIds: string[]): Promise<BoxedResponse<IEsploraTransaction[], EsploraFetchError>>;
|
|
216
|
+
esplora_getblocktiphash(): Promise<BoxedResponse<string, EsploraFetchError>>;
|
|
217
|
+
_esplora_getrawblock(blockHash: string): Promise<BoxedResponse<string, EsploraFetchError>>;
|
|
218
|
+
esplora_getrawblocktip(): Promise<BoxedResponse<string, EsploraFetchError>>;
|
|
189
219
|
esplora_gettransaction(transactionId: string): Promise<BoxedResponse<IEsploraTransaction, EsploraFetchError>>;
|
|
190
220
|
esplora_getrawtransaction(transactionId: string): Promise<BoxedResponse<string, EsploraFetchError>>;
|
|
191
221
|
esplora_getspendableinputs(utxoList: EsploraUtxo[]): Promise<BoxedResponse<IEsploraSpendableUtxo[], EsploraFetchError>>;
|
|
@@ -585,6 +615,10 @@ declare class BaseRpcProvider {
|
|
|
585
615
|
}
|
|
586
616
|
|
|
587
617
|
declare const stripHex: (s: string) => string;
|
|
618
|
+
declare function toU64LittleEndianHex(numStr: string): string;
|
|
619
|
+
declare function makeFakeBlock(height: number | bigint): string;
|
|
620
|
+
declare function toU64BigEndianHex(numStr: string): string;
|
|
621
|
+
declare function toU128LittleEndianHex(numStr: string): string;
|
|
588
622
|
declare function mapToPrimitives(v: any): any;
|
|
589
623
|
declare function unmapFromPrimitives(v: any): any;
|
|
590
624
|
declare function parseSimulateReturn(v: string): AlkanesParsedSimulationResult | undefined;
|
|
@@ -1478,5 +1512,5 @@ declare const TokenContract_base: new (provider: Provider, alkaneId: AlkaneId, s
|
|
|
1478
1512
|
declare class TokenContract extends TokenContract_base {
|
|
1479
1513
|
}
|
|
1480
1514
|
|
|
1481
|
-
export { AddressType, AlkanesBaseContract, AlkanesExecuteError, AlkanesFetchError, AlkanesInscription, AlkanesRpcProvider, AlkanesSimulationError, AlkanesTraceError, BaseRpcProvider, DecodableAlkanesResponse, DecodeError, EcPair, ElectrumApiProvider, Encodable, EncodeError, EsploraFetchError, OrdFetchError, OrdRpcProvider, ParsableAlkaneId, ProtostoneTransaction, ProtostoneTransactionWithInscription, Provider, RpcError, RunesFetchError, RunesRpcProvider, SandshrewFetchError, SandshrewRpcProvider, TokenABI, TokenContract, abi, addInputDynamic, addressFormats, addressNameToType, addressTypeToName, assertHex, buildRpcCall, calculateTaprootTxSize, decodeAlkanesTrace, decodeCBOR, excludeFields, execute, extractAbiErrorMessage, extractWithDummySigs, formatInputsToSign, getAddressType, getDummyProtostoneTransaction, getEstimatedFee, getProtostoneTransactionsWithInscription, getProtostoneUnsignedPsbtBase64, getVSize, hexToUint8Array, mapToPrimitives, minimumFee, parseSimulateReturn, psbtBuilder, redeemTypeFromOutput, reverseHexBytes, schemaAlkaneId, simulate, sleep, stripHex, tapTweakHash, toEsploraTx, toFormattedUtxo, trimUndefined, tweakSigner, u128Schema, unmapFromPrimitives, witnessStackToScriptWitness };
|
|
1515
|
+
export { AddressType, AlkanesBaseContract, AlkanesExecuteError, AlkanesFetchError, AlkanesInscription, AlkanesRpcProvider, AlkanesSimulationError, AlkanesTraceError, BaseRpcProvider, DecodableAlkanesResponse, DecodeError, EcPair, ElectrumApiProvider, Encodable, EncodeError, EsploraFetchError, OrdFetchError, OrdRpcProvider, ParsableAlkaneId, ProtostoneTransaction, ProtostoneTransactionWithInscription, Provider, RpcError, RunesFetchError, RunesRpcProvider, SandshrewFetchError, SandshrewRpcProvider, TokenABI, TokenContract, abi, addInputDynamic, addressFormats, addressNameToType, addressTypeToName, assertHex, buildRpcCall, calculateTaprootTxSize, decodeAlkanesTrace, decodeCBOR, excludeFields, execute, extractAbiErrorMessage, extractWithDummySigs, formatInputsToSign, getAddressType, getDummyProtostoneTransaction, getEstimatedFee, getProtostoneTransactionsWithInscription, getProtostoneUnsignedPsbtBase64, getVSize, hexToUint8Array, makeFakeBlock, mapToPrimitives, minimumFee, parseSimulateReturn, psbtBuilder, redeemTypeFromOutput, reverseHexBytes, schemaAlkaneId, simulate, sleep, stripHex, tapTweakHash, toEsploraTx, toFormattedUtxo, toU128LittleEndianHex, toU64BigEndianHex, toU64LittleEndianHex, trimUndefined, tweakSigner, u128Schema, unmapFromPrimitives, witnessStackToScriptWitness };
|
|
1482
1516
|
export type { Account, AddressKey, Alkane, AlkaneDetails, AlkaneEncoded, AlkaneEncodedSimulationRequest, AlkaneId, AlkaneReadableId, AlkaneRune, AlkaneSimulateRequest, AlkaneToken, AlkanesByAddressOutpoint, AlkanesByAddressResponse, AlkanesByAddressRuneBalance, AlkanesExecuteResponse, AlkanesOutpoint, AlkanesOutpointExtended, AlkanesOutpoints, AlkanesOutpointsExtended, AlkanesParsedSimulationResult, AlkanesParsedTraceResult, AlkanesPushExecuteResponse, AlkanesRawSimulationResponse, AlkanesSimulationResult, AlkanesTraceCreateEvent, AlkanesTraceEncodedCreateEvent, AlkanesTraceEncodedEvent, AlkanesTraceEncodedInvokeEvent, AlkanesTraceEncodedResult, AlkanesTraceEncodedReturnEvent, AlkanesTraceEvent, AlkanesTraceInvokeEvent, AlkanesTraceResult, AlkanesTraceReturnEvent, AlkanesUtxo, AlkanesUtxoBalance, AlkanesUtxoEntry, AvailableDecodeKind, AvailableEncodeKind, CustomSpec, Dec, DecodedCBOR, DecodedCBORValue, DecoderFns, Enc, EncodedAlkaneId, EncoderFns, EsploraAddressResponse, EsploraAddressStats, EsploraUtxo, ExecuteSpec, Expand, FormattedUtxo, HDPaths, IDecodableAlkanesResponse, IEncodable, IEsploraBlockHeader, IEsploraPrevout, IEsploraSpendableUtxo, IEsploraTransaction, IEsploraTransactionStatus, IEsploraVin, IEsploraVout, ISchemaAlkaneId, OpcodeTable, OrdBlock, OrdInscription, OrdOutput, OrdOutputRune, OrdPaginatedIds, OrdSat, ProtoRunesToken, ProtostoneTransactionOptions, ProtostoneTransactionOptionsPartial, ProviderConfig, PsbtInputExtended, ResolveSchema, RpcCall, RpcResponse, RpcTuple, Rune, RuneBalance, RuneName, RunesAddressResult, RunesOutpoint, RunesOutpointResult, Schema, SingularAlkanesTransfer, SingularBTCTransfer, SingularTransfer, SpendStrategy, ViewSpec, WalletStandard };
|
package/dist/index.js
CHANGED
|
@@ -34791,6 +34791,7 @@ __export(src_exports, {
|
|
|
34791
34791
|
getProtostoneUnsignedPsbtBase64: () => getProtostoneUnsignedPsbtBase64,
|
|
34792
34792
|
getVSize: () => getVSize,
|
|
34793
34793
|
hexToUint8Array: () => hexToUint8Array,
|
|
34794
|
+
makeFakeBlock: () => makeFakeBlock,
|
|
34794
34795
|
mapToPrimitives: () => mapToPrimitives,
|
|
34795
34796
|
minimumFee: () => minimumFee,
|
|
34796
34797
|
parseSimulateReturn: () => parseSimulateReturn,
|
|
@@ -34804,6 +34805,9 @@ __export(src_exports, {
|
|
|
34804
34805
|
tapTweakHash: () => tapTweakHash,
|
|
34805
34806
|
toEsploraTx: () => toEsploraTx,
|
|
34806
34807
|
toFormattedUtxo: () => toFormattedUtxo,
|
|
34808
|
+
toU128LittleEndianHex: () => toU128LittleEndianHex,
|
|
34809
|
+
toU64BigEndianHex: () => toU64BigEndianHex,
|
|
34810
|
+
toU64LittleEndianHex: () => toU64LittleEndianHex,
|
|
34807
34811
|
trimUndefined: () => trimUndefined,
|
|
34808
34812
|
tweakSigner: () => tweakSigner,
|
|
34809
34813
|
u128Schema: () => u128Schema,
|
|
@@ -37299,7 +37303,8 @@ var ProtostoneTransaction = class {
|
|
|
37299
37303
|
this.fee = Math.max(baseFee, this.MINIMUM_FEE);
|
|
37300
37304
|
}
|
|
37301
37305
|
calcCumulativeSpendRequirements() {
|
|
37302
|
-
this.cumulativeSpendRequirementBtc = this.fee + this.MINIMUM_PROTOCOL_DUST *
|
|
37306
|
+
this.cumulativeSpendRequirementBtc = this.fee + this.MINIMUM_PROTOCOL_DUST * (this.transactionOptions.transfers?.length ?? 0) + this.MINIMUM_PROTOCOL_DUST;
|
|
37307
|
+
console.log(this.cumulativeSpendRequirementBtc);
|
|
37303
37308
|
this.cumulativeSpendRequirementAlkanes = this.transactionOptions.transfers.reduce(
|
|
37304
37309
|
(acc, transfer) => {
|
|
37305
37310
|
if (isBTCTransfer(transfer)) {
|
|
@@ -37527,7 +37532,7 @@ var ProtostoneTransaction = class {
|
|
|
37527
37532
|
),
|
|
37528
37533
|
// Convert bigint to string for JSON compatibility
|
|
37529
37534
|
amount: (0, import_integer.u128)(transfer.amount),
|
|
37530
|
-
output: (0, import_integer.u32)(outputIds[address3] +
|
|
37535
|
+
output: (0, import_integer.u32)(outputIds[address3] + 1)
|
|
37531
37536
|
};
|
|
37532
37537
|
if (!alkanesEdicts[address3]) {
|
|
37533
37538
|
alkanesEdicts[address3] = {};
|
|
@@ -37547,6 +37552,7 @@ var ProtostoneTransaction = class {
|
|
|
37547
37552
|
output: edict.output
|
|
37548
37553
|
}))
|
|
37549
37554
|
);
|
|
37555
|
+
console.log(transactionEdicts[0]);
|
|
37550
37556
|
return transactionEdicts;
|
|
37551
37557
|
}
|
|
37552
37558
|
addProtostoneData(edicts) {
|
|
@@ -42513,6 +42519,53 @@ var ElectrumApiProvider = class {
|
|
|
42513
42519
|
);
|
|
42514
42520
|
}
|
|
42515
42521
|
}
|
|
42522
|
+
async esplora_getblocktiphash() {
|
|
42523
|
+
try {
|
|
42524
|
+
const requestUrl = `${this.electrumApiUrl}/blocks/tip/hash`;
|
|
42525
|
+
const httpResponse = await fetch(requestUrl);
|
|
42526
|
+
if (!httpResponse.ok) {
|
|
42527
|
+
return new BoxedError(
|
|
42528
|
+
"UnknownError" /* UnknownError */,
|
|
42529
|
+
`Failed to fetch tip hash from ${requestUrl}: ${httpResponse.statusText}`
|
|
42530
|
+
);
|
|
42531
|
+
}
|
|
42532
|
+
const tipHash = (await httpResponse.text()).trim();
|
|
42533
|
+
return new BoxedSuccess(tipHash);
|
|
42534
|
+
} catch (error) {
|
|
42535
|
+
return new BoxedError(
|
|
42536
|
+
"UnknownError" /* UnknownError */,
|
|
42537
|
+
`Failed to fetch tip hash: ${error.message}`
|
|
42538
|
+
);
|
|
42539
|
+
}
|
|
42540
|
+
}
|
|
42541
|
+
async _esplora_getrawblock(blockHash) {
|
|
42542
|
+
try {
|
|
42543
|
+
const requestUrl = `${this.electrumApiUrl}/block/${blockHash}/raw`;
|
|
42544
|
+
const httpResponse = await fetch(requestUrl);
|
|
42545
|
+
if (!httpResponse.ok) {
|
|
42546
|
+
return new BoxedError(
|
|
42547
|
+
"UnknownError" /* UnknownError */,
|
|
42548
|
+
`Failed to fetch raw block ${blockHash} from ${requestUrl}: ${httpResponse.statusText}`
|
|
42549
|
+
);
|
|
42550
|
+
}
|
|
42551
|
+
const bytes = new Uint8Array(await httpResponse.arrayBuffer());
|
|
42552
|
+
const rawHex = Array.from(
|
|
42553
|
+
bytes,
|
|
42554
|
+
(b) => b.toString(16).padStart(2, "0")
|
|
42555
|
+
).join("");
|
|
42556
|
+
return new BoxedSuccess("0x" + rawHex);
|
|
42557
|
+
} catch (error) {
|
|
42558
|
+
return new BoxedError(
|
|
42559
|
+
"UnknownError" /* UnknownError */,
|
|
42560
|
+
`Failed to fetch raw block ${blockHash}: ${error.message}`
|
|
42561
|
+
);
|
|
42562
|
+
}
|
|
42563
|
+
}
|
|
42564
|
+
async esplora_getrawblocktip() {
|
|
42565
|
+
const tipHashResponse = await this.esplora_getblocktiphash();
|
|
42566
|
+
if (isBoxedError(tipHashResponse)) return tipHashResponse;
|
|
42567
|
+
return this._esplora_getrawblock(tipHashResponse.data);
|
|
42568
|
+
}
|
|
42516
42569
|
/*
|
|
42517
42570
|
async esplora_getbulktransactions(
|
|
42518
42571
|
transactionIds: string[],
|
|
@@ -45066,6 +45119,42 @@ var OrdRpcProvider = class {
|
|
|
45066
45119
|
|
|
45067
45120
|
// src/apis/alkanes/utils.ts
|
|
45068
45121
|
var stripHex = (s) => s.startsWith("0x") ? s.slice(2) : s;
|
|
45122
|
+
function toU64LittleEndianHex(numStr) {
|
|
45123
|
+
const num = BigInt(numStr);
|
|
45124
|
+
const hex = num.toString(16).padStart(16, "0");
|
|
45125
|
+
const bytes = hex.match(/.{2}/g);
|
|
45126
|
+
if (!bytes) throw new Error("Invalid hex conversion");
|
|
45127
|
+
const littleEndian = bytes.reverse().join("");
|
|
45128
|
+
return `0x${littleEndian}`;
|
|
45129
|
+
}
|
|
45130
|
+
function makeFakeBlock(height) {
|
|
45131
|
+
const buf = new Uint8Array(80);
|
|
45132
|
+
const h = BigInt(height);
|
|
45133
|
+
for (let i = 0; i < 8; i++) {
|
|
45134
|
+
buf[72 + i] = Number(h >> BigInt(8 * i) & 0xffn);
|
|
45135
|
+
}
|
|
45136
|
+
const hex = Array.from(buf, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
45137
|
+
return `${hex}`;
|
|
45138
|
+
}
|
|
45139
|
+
function toU64BigEndianHex(numStr) {
|
|
45140
|
+
const MAX_U64 = BigInt("0xffffffffffffffff");
|
|
45141
|
+
const num = BigInt(numStr);
|
|
45142
|
+
if (num < 0n || num > MAX_U64) {
|
|
45143
|
+
throw new RangeError("Value exceeds u64 range");
|
|
45144
|
+
}
|
|
45145
|
+
const hex = num.toString(16).padStart(16, "0");
|
|
45146
|
+
return `0x${hex}`;
|
|
45147
|
+
}
|
|
45148
|
+
function toU128LittleEndianHex(numStr) {
|
|
45149
|
+
const MAX_U1282 = BigInt("0xffffffffffffffffffffffffffffffff");
|
|
45150
|
+
const num = BigInt(numStr);
|
|
45151
|
+
if (num < 0n || num > MAX_U1282) {
|
|
45152
|
+
throw new RangeError("Value exceeds u128 range");
|
|
45153
|
+
}
|
|
45154
|
+
const hex = num.toString(16).padStart(32, "0");
|
|
45155
|
+
const littleEndian = hex.match(/.{2}/g).reverse().join("");
|
|
45156
|
+
return `0x${littleEndian}`;
|
|
45157
|
+
}
|
|
45069
45158
|
function mapToPrimitives(v) {
|
|
45070
45159
|
switch (typeof v) {
|
|
45071
45160
|
case "bigint":
|
|
@@ -45074,7 +45163,9 @@ function mapToPrimitives(v) {
|
|
|
45074
45163
|
if (v === null) return null;
|
|
45075
45164
|
if (Buffer.isBuffer(v)) return "0x" + v.toString("hex");
|
|
45076
45165
|
if (Array.isArray(v)) return v.map(mapToPrimitives);
|
|
45077
|
-
return Object.fromEntries(
|
|
45166
|
+
return Object.fromEntries(
|
|
45167
|
+
Object.entries(v).map(([k, val]) => [k, mapToPrimitives(val)])
|
|
45168
|
+
);
|
|
45078
45169
|
}
|
|
45079
45170
|
default:
|
|
45080
45171
|
return v;
|
|
@@ -45083,13 +45174,16 @@ function mapToPrimitives(v) {
|
|
|
45083
45174
|
function unmapFromPrimitives(v) {
|
|
45084
45175
|
switch (typeof v) {
|
|
45085
45176
|
case "string":
|
|
45086
|
-
if (v.startsWith("0x") && v !== "0x")
|
|
45177
|
+
if (v.startsWith("0x") && v !== "0x")
|
|
45178
|
+
return Buffer.from(stripHex(v), "hex");
|
|
45087
45179
|
if (!isNaN(v)) return BigInt(v);
|
|
45088
45180
|
return v;
|
|
45089
45181
|
case "object": {
|
|
45090
45182
|
if (v === null) return null;
|
|
45091
45183
|
if (Array.isArray(v)) return v.map(unmapFromPrimitives);
|
|
45092
|
-
return Object.fromEntries(
|
|
45184
|
+
return Object.fromEntries(
|
|
45185
|
+
Object.entries(v).map(([k, val]) => [k, unmapFromPrimitives(val)])
|
|
45186
|
+
);
|
|
45093
45187
|
}
|
|
45094
45188
|
default:
|
|
45095
45189
|
return v;
|
|
@@ -45099,7 +45193,9 @@ function parseSimulateReturn(v) {
|
|
|
45099
45193
|
if (v === "0x") return void 0;
|
|
45100
45194
|
const toUtf8 = Buffer.from(stripHex(v), "hex").toString("utf8");
|
|
45101
45195
|
const isUtf8 = !/[\uFFFD]/.test(toUtf8);
|
|
45102
|
-
const rev = Buffer.from(
|
|
45196
|
+
const rev = Buffer.from(
|
|
45197
|
+
Array.from(Buffer.from(stripHex(v), "hex")).reverse()
|
|
45198
|
+
).toString("hex");
|
|
45103
45199
|
return {
|
|
45104
45200
|
string: isUtf8 ? toUtf8 : "0x" + stripHex(v),
|
|
45105
45201
|
bytes: "0x" + stripHex(v),
|
|
@@ -45216,6 +45312,7 @@ var AlkanesRpcProvider = class {
|
|
|
45216
45312
|
payload: ["alkanes_trace", [{ txid: leTxid, vout }]],
|
|
45217
45313
|
call: async () => {
|
|
45218
45314
|
try {
|
|
45315
|
+
await this.provider.pacer.waitForPacer();
|
|
45219
45316
|
const encoded = consumeOrThrow(
|
|
45220
45317
|
await this.rpc("alkanes_trace", [
|
|
45221
45318
|
{ txid: leTxid, vout }
|
|
@@ -45294,7 +45391,7 @@ var AlkanesRpcProvider = class {
|
|
|
45294
45391
|
alkanes: req.alkanes ?? [],
|
|
45295
45392
|
transaction: req.transaction ?? "0x",
|
|
45296
45393
|
block: "0x",
|
|
45297
|
-
height:
|
|
45394
|
+
height: "908474",
|
|
45298
45395
|
txindex: req.txindex ?? 0,
|
|
45299
45396
|
target: {
|
|
45300
45397
|
block: req.target?.block?.toString() ?? "0",
|
|
@@ -45305,6 +45402,7 @@ var AlkanesRpcProvider = class {
|
|
|
45305
45402
|
refundPointer: req.refundPointer ?? 0,
|
|
45306
45403
|
vout: req.vout ?? 0
|
|
45307
45404
|
};
|
|
45405
|
+
console.log(merged);
|
|
45308
45406
|
const res = await this.rpc(
|
|
45309
45407
|
"alkanes_simulate",
|
|
45310
45408
|
[merged]
|
|
@@ -45647,27 +45745,96 @@ var schemaAlkaneId = import_borsher4.BorshSchema.Struct({
|
|
|
45647
45745
|
tx: import_borsher4.BorshSchema.u64
|
|
45648
45746
|
});
|
|
45649
45747
|
|
|
45748
|
+
// src/pacer.ts
|
|
45749
|
+
var WaitPacer = class {
|
|
45750
|
+
maxPerInterval;
|
|
45751
|
+
intervalMs;
|
|
45752
|
+
minGapMs;
|
|
45753
|
+
// track start times within the sliding window
|
|
45754
|
+
starts = [];
|
|
45755
|
+
lastStart = 0;
|
|
45756
|
+
// serialize callers so their start times are paced correctly
|
|
45757
|
+
tail = Promise.resolve();
|
|
45758
|
+
constructor(opts) {
|
|
45759
|
+
this.maxPerInterval = Math.max(1, opts.maxPerInterval);
|
|
45760
|
+
this.intervalMs = Math.max(1, opts.intervalMs);
|
|
45761
|
+
this.minGapMs = Math.floor(this.intervalMs / this.maxPerInterval);
|
|
45762
|
+
}
|
|
45763
|
+
setRate(maxPerInterval, intervalMs) {
|
|
45764
|
+
this.maxPerInterval = Math.max(1, maxPerInterval);
|
|
45765
|
+
this.intervalMs = Math.max(1, intervalMs);
|
|
45766
|
+
this.minGapMs = Math.floor(this.intervalMs / this.maxPerInterval);
|
|
45767
|
+
}
|
|
45768
|
+
now() {
|
|
45769
|
+
return Date.now();
|
|
45770
|
+
}
|
|
45771
|
+
sleep(ms) {
|
|
45772
|
+
return ms > 0 ? new Promise((r) => setTimeout(r, ms)) : Promise.resolve();
|
|
45773
|
+
}
|
|
45774
|
+
pruneWindow(now) {
|
|
45775
|
+
const cutoff = now - this.intervalMs;
|
|
45776
|
+
while (this.starts.length && this.starts[0] <= cutoff) this.starts.shift();
|
|
45777
|
+
}
|
|
45778
|
+
/** Await this immediately before the call that could rate-limit */
|
|
45779
|
+
waitForPacer() {
|
|
45780
|
+
const ticket = this.tail.then(async () => {
|
|
45781
|
+
while (true) {
|
|
45782
|
+
const now = this.now();
|
|
45783
|
+
this.pruneWindow(now);
|
|
45784
|
+
if (this.starts.length >= this.maxPerInterval) {
|
|
45785
|
+
const earliest = this.starts[0];
|
|
45786
|
+
const waitUntil = earliest + this.intervalMs;
|
|
45787
|
+
await this.sleep(Math.max(0, waitUntil - this.now()));
|
|
45788
|
+
continue;
|
|
45789
|
+
}
|
|
45790
|
+
const earliestStart = this.lastStart + this.minGapMs;
|
|
45791
|
+
const delay = Math.max(0, earliestStart - now);
|
|
45792
|
+
if (delay > 0) {
|
|
45793
|
+
await this.sleep(delay);
|
|
45794
|
+
continue;
|
|
45795
|
+
}
|
|
45796
|
+
const startTs = this.now();
|
|
45797
|
+
this.lastStart = startTs;
|
|
45798
|
+
this.starts.push(startTs);
|
|
45799
|
+
break;
|
|
45800
|
+
}
|
|
45801
|
+
});
|
|
45802
|
+
this.tail = ticket.catch(() => {
|
|
45803
|
+
});
|
|
45804
|
+
return ticket;
|
|
45805
|
+
}
|
|
45806
|
+
};
|
|
45807
|
+
|
|
45650
45808
|
// src/provider.ts
|
|
45651
45809
|
var Provider = class {
|
|
45652
45810
|
sandshrewUrl;
|
|
45653
45811
|
electrumApiUrl;
|
|
45654
45812
|
network;
|
|
45655
45813
|
explorerUrl;
|
|
45814
|
+
pacerSettings = {
|
|
45815
|
+
intervalMs: 1e3,
|
|
45816
|
+
maxPerInterval: 10
|
|
45817
|
+
};
|
|
45656
45818
|
btcTicker;
|
|
45819
|
+
jitterMs = 1e3;
|
|
45820
|
+
// 1 second
|
|
45657
45821
|
rpc;
|
|
45658
45822
|
defaultFeeRate;
|
|
45659
45823
|
TIMEOUT_MS = 6e4 * 5;
|
|
45660
45824
|
// 5 minutes
|
|
45661
45825
|
INTERVAL_MS = 5e3;
|
|
45662
45826
|
// 5 seconds
|
|
45827
|
+
pacer;
|
|
45663
45828
|
constructor(config) {
|
|
45664
45829
|
this.sandshrewUrl = config.sandshrewUrl;
|
|
45665
45830
|
this.electrumApiUrl = config.electrumApiUrl;
|
|
45666
45831
|
this.network = config.network;
|
|
45667
45832
|
this.explorerUrl = config.explorerUrl.replace(/\/+$/, "");
|
|
45668
45833
|
this.btcTicker = config.btcTicker ?? "BTC";
|
|
45834
|
+
this.pacerSettings = config.pacerSettings ?? this.pacerSettings;
|
|
45669
45835
|
this.defaultFeeRate = config.defaultFeeRate ?? 5;
|
|
45670
45836
|
this.rpc = new BaseRpcProvider(this);
|
|
45837
|
+
this.pacer = new WaitPacer(this.pacerSettings);
|
|
45671
45838
|
}
|
|
45672
45839
|
txUrl(txid) {
|
|
45673
45840
|
return `${this.explorerUrl}/tx/${txid}`;
|
|
@@ -45863,6 +46030,7 @@ bitcoin2.initEccLib(ecc);
|
|
|
45863
46030
|
getProtostoneUnsignedPsbtBase64,
|
|
45864
46031
|
getVSize,
|
|
45865
46032
|
hexToUint8Array,
|
|
46033
|
+
makeFakeBlock,
|
|
45866
46034
|
mapToPrimitives,
|
|
45867
46035
|
minimumFee,
|
|
45868
46036
|
parseSimulateReturn,
|
|
@@ -45876,6 +46044,9 @@ bitcoin2.initEccLib(ecc);
|
|
|
45876
46044
|
tapTweakHash,
|
|
45877
46045
|
toEsploraTx,
|
|
45878
46046
|
toFormattedUtxo,
|
|
46047
|
+
toU128LittleEndianHex,
|
|
46048
|
+
toU64BigEndianHex,
|
|
46049
|
+
toU64LittleEndianHex,
|
|
45879
46050
|
trimUndefined,
|
|
45880
46051
|
tweakSigner,
|
|
45881
46052
|
u128Schema,
|