@mnee/ts-sdk 1.0.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 +256 -0
- package/dist/batch.d.ts +116 -0
- package/dist/constants.d.ts +12 -0
- package/dist/hdWallet.d.ts +111 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +216 -0
- package/dist/index.modern.js +2 -0
- package/dist/index.modern.js.map +1 -0
- package/dist/index.module.js +2 -0
- package/dist/index.module.js.map +1 -0
- package/dist/index.umd.js +2 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/mnee.types.d.ts +251 -0
- package/dist/mneeCosignTemplate.d.ts +54 -0
- package/dist/mneeService.d.ts +51 -0
- package/package.json +65 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { MNEEBalance, MNEEConfig, SdkConfig, ParseTxResponse, ParseTxExtendedResponse, ParseOptions, SendMNEE, TransferResponse, TransferStatus, TransferMultiOptions, TxHistoryResponse, AddressHistoryParams, Inscription, ParsedCosigner, MNEEUtxo, TransferOptions } from './mnee.types.js';
|
|
2
|
+
import { Script } from '@bsv/sdk';
|
|
3
|
+
import { HDWallet, HDWalletOptions } from './hdWallet.js';
|
|
4
|
+
import { Batch } from './batch.js';
|
|
5
|
+
export * from './mnee.types.js';
|
|
6
|
+
export interface MneeInterface {
|
|
7
|
+
config(): Promise<MNEEConfig>;
|
|
8
|
+
balance(address: string): Promise<MNEEBalance>;
|
|
9
|
+
balances(addresses: string[]): Promise<MNEEBalance[]>;
|
|
10
|
+
getUtxos(address: string | string[], page?: number, size?: number, order?: 'asc' | 'desc'): Promise<MNEEUtxo[]>;
|
|
11
|
+
getEnoughUtxos(address: string, totalAtomicTokenAmount: number): Promise<MNEEUtxo[]>;
|
|
12
|
+
getAllUtxos(address: string): Promise<MNEEUtxo[]>;
|
|
13
|
+
validateMneeTx(rawTxHex: string, request?: SendMNEE[]): Promise<boolean>;
|
|
14
|
+
transfer(request: SendMNEE[], wif: string, transferOptions?: TransferOptions): Promise<TransferResponse>;
|
|
15
|
+
transferMulti(options: TransferMultiOptions, transferOptions?: TransferOptions): Promise<TransferResponse>;
|
|
16
|
+
submitRawTx(rawTxHex: string): Promise<TransferResponse>;
|
|
17
|
+
getTxStatus(ticketId: string): Promise<TransferStatus>;
|
|
18
|
+
toAtomicAmount(amount: number): number;
|
|
19
|
+
fromAtomicAmount(amount: number): number;
|
|
20
|
+
recentTxHistory(address: string, fromScore?: number, limit?: number, order?: 'asc' | 'desc'): Promise<TxHistoryResponse>;
|
|
21
|
+
recentTxHistories(params: AddressHistoryParams[]): Promise<TxHistoryResponse[]>;
|
|
22
|
+
parseTx(txid: string, options?: ParseOptions): Promise<ParseTxResponse | ParseTxExtendedResponse>;
|
|
23
|
+
parseTxFromRawTx(rawTxHex: string, options?: ParseOptions): Promise<ParseTxResponse | ParseTxExtendedResponse>;
|
|
24
|
+
parseInscription(script: Script): Inscription | undefined;
|
|
25
|
+
parseCosignerScripts(scripts: Script[]): ParsedCosigner[];
|
|
26
|
+
HDWallet(mnemonic: string, options: HDWalletOptions): HDWallet;
|
|
27
|
+
batch(): Batch;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Represents the Mnee class that provides methods to interact with the MNEE service.
|
|
31
|
+
*/
|
|
32
|
+
export default class Mnee implements MneeInterface {
|
|
33
|
+
private service;
|
|
34
|
+
private _batch?;
|
|
35
|
+
/**
|
|
36
|
+
* Static reference to HDWallet class for accessing static methods
|
|
37
|
+
* @example
|
|
38
|
+
* const mnemonic = Mnee.HDWallet.generateMnemonic();
|
|
39
|
+
* const isValid = Mnee.HDWallet.isValidMnemonic(mnemonic);
|
|
40
|
+
*/
|
|
41
|
+
static HDWallet: typeof HDWallet;
|
|
42
|
+
constructor(config: SdkConfig);
|
|
43
|
+
/**
|
|
44
|
+
* Validates an MNEE transaction.
|
|
45
|
+
*
|
|
46
|
+
* @param rawTxHex - The raw transaction hex string to validate.
|
|
47
|
+
* @param request - An array of SendMNEE objects representing the transfer details. Use this parameter to validate the transaction against the specified transfer details. If it is not provided, it will only validate that the transaction is well-formed with the cosigner.
|
|
48
|
+
* @returns A promise that resolves to a boolean indicating whether the transaction is valid.
|
|
49
|
+
*/
|
|
50
|
+
validateMneeTx(rawTxHex: string, request?: SendMNEE[]): Promise<boolean>;
|
|
51
|
+
/**
|
|
52
|
+
* Converts a given amount to its atomic representation based on the specified number.
|
|
53
|
+
*
|
|
54
|
+
* @param amount - The amount to be converted.
|
|
55
|
+
* @returns The atomic representation of the given amount.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* toAtomicAmount(1.5); // 150000
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
toAtomicAmount(amount: number): number;
|
|
63
|
+
/**
|
|
64
|
+
* Converts a given atomic amount to its human-readable representation.
|
|
65
|
+
*
|
|
66
|
+
* @param amount - The atomic amount to be converted.
|
|
67
|
+
* @returns The human-readable representation of the given atomic amount.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* fromAtomicAmount(150000); // 1.5
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
fromAtomicAmount(amount: number): number;
|
|
75
|
+
/**
|
|
76
|
+
* Retrieves the configuration for the MNEE service.
|
|
77
|
+
*
|
|
78
|
+
* @returns {Promise<MNEEConfig>} A promise that resolves to the MNEE configuration object.
|
|
79
|
+
*/
|
|
80
|
+
config(): Promise<MNEEConfig>;
|
|
81
|
+
/**
|
|
82
|
+
* Retrieves the balance for a given address.
|
|
83
|
+
*
|
|
84
|
+
* @param address - The address to retrieve the balance for.
|
|
85
|
+
* @returns A promise that resolves to a `MNEEBalance` object containing the balance details.
|
|
86
|
+
*/
|
|
87
|
+
balance(address: string): Promise<MNEEBalance>;
|
|
88
|
+
/**
|
|
89
|
+
* Retrieves the balances for multiple addresses.
|
|
90
|
+
*
|
|
91
|
+
* @param addresses - An array of addresses to retrieve the balances for.
|
|
92
|
+
* @returns A promise that resolves to an array of `MNEEBalance` objects containing the balance details for each address.
|
|
93
|
+
*/
|
|
94
|
+
balances(addresses: string[]): Promise<MNEEBalance[]>;
|
|
95
|
+
/**
|
|
96
|
+
* Retrieves the UTXOs for a given address.
|
|
97
|
+
*
|
|
98
|
+
* @param address - The address to retrieve the UTXOs for.
|
|
99
|
+
* @returns A promise that resolves to an array of `MNEEUtxo` objects containing the UTXO details.
|
|
100
|
+
*/
|
|
101
|
+
getUtxos(address: string | string[], page?: number, size?: number, order?: 'asc' | 'desc'): Promise<MNEEUtxo[]>;
|
|
102
|
+
/**
|
|
103
|
+
* Retrieves the UTXOs for a given address that have enough balance to cover the total atomic token amount.
|
|
104
|
+
*
|
|
105
|
+
* @param address - The address to retrieve the UTXOs for.
|
|
106
|
+
* @param totalAtomicTokenAmount - The total atomic token amount to cover.
|
|
107
|
+
* @returns A promise that resolves to an array of `MNEEUtxo` objects containing the UTXO details.
|
|
108
|
+
*/
|
|
109
|
+
getEnoughUtxos(address: string, totalAtomicTokenAmount: number): Promise<MNEEUtxo[]>;
|
|
110
|
+
/**
|
|
111
|
+
* Retrieves all UTXOs for a given address.
|
|
112
|
+
*
|
|
113
|
+
* @param address - The address to retrieve the UTXOs for.
|
|
114
|
+
* @returns A promise that resolves to an array of `MNEEUtxo` objects containing the UTXO details.
|
|
115
|
+
*/
|
|
116
|
+
getAllUtxos(address: string): Promise<MNEEUtxo[]>;
|
|
117
|
+
/**
|
|
118
|
+
* Transfers the specified MNEE tokens using the provided WIF (Wallet Import Format) key.
|
|
119
|
+
*
|
|
120
|
+
* @param {SendMNEE[]} request - An array of SendMNEE objects representing the transfer details.
|
|
121
|
+
* @param {string} wif - The Wallet Import Format key used to authorize the transfer.
|
|
122
|
+
* @returns {Promise<TransferResponse>} A promise that resolves to a TransferResponse object containing the result of the transfer.
|
|
123
|
+
*/
|
|
124
|
+
transfer(request: SendMNEE[], wif: string, transferOptions?: TransferOptions): Promise<TransferResponse>;
|
|
125
|
+
/**
|
|
126
|
+
* Transfers MNEE tokens from multiple source UTXOs with different private keys. This is a more advanced method that allows you to control the UTXOs used in the transfer along with associated private keys.
|
|
127
|
+
*
|
|
128
|
+
* @param options - The transfer options including inputs, recipients, and optional change address.
|
|
129
|
+
* @returns A promise that resolves to a TransferResponse object containing the result of the transfer.
|
|
130
|
+
*/
|
|
131
|
+
transferMulti(options: TransferMultiOptions, transferOptions?: TransferOptions): Promise<TransferResponse>;
|
|
132
|
+
/**
|
|
133
|
+
* Submits a partially signed raw transaction to the MNEE network. This is useful when you have a raw transaction hex string that you have already signed, but you need to submit it to the MNEE network.
|
|
134
|
+
*
|
|
135
|
+
* @param rawTxHex - The raw transaction hex string to submit.
|
|
136
|
+
* @returns A promise that resolves to a TransferResponse object containing the result of the transfer.
|
|
137
|
+
*/
|
|
138
|
+
submitRawTx(rawTxHex: string, transferOptions?: TransferOptions): Promise<TransferResponse>;
|
|
139
|
+
/**
|
|
140
|
+
* Gets the status of a transfer transaction using its ticket ID.
|
|
141
|
+
*
|
|
142
|
+
* @param ticketId - The ticket ID returned from submitRawTx or V2 transfer endpoint.
|
|
143
|
+
* @returns A promise that resolves to a TransferStatus object containing the current status of the transfer.
|
|
144
|
+
*/
|
|
145
|
+
getTxStatus(ticketId: string): Promise<TransferStatus>;
|
|
146
|
+
/**
|
|
147
|
+
* Retrieves the recent transaction history for a given address.
|
|
148
|
+
*
|
|
149
|
+
* @param address - The address to retrieve the transaction history for.
|
|
150
|
+
* @param fromScore - The starting score to retrieve the transaction history from.
|
|
151
|
+
* @param limit - The maximum number of transactions to retrieve.
|
|
152
|
+
* @returns A promise that resolves to a TxHistoryResponse object containing the transaction
|
|
153
|
+
* history and the next score to retrieve additional transactions.
|
|
154
|
+
*/
|
|
155
|
+
recentTxHistory(address: string, fromScore?: number, limit?: number, order?: 'asc' | 'desc'): Promise<TxHistoryResponse>;
|
|
156
|
+
/**
|
|
157
|
+
* Retrieves the recent transaction histories for multiple addresses.
|
|
158
|
+
*
|
|
159
|
+
* @param params - An array of address parameters, each containing an address, optional fromScore, and optional limit.
|
|
160
|
+
* @returns A promise that resolves to an array of TxHistoryResponse objects containing the transaction
|
|
161
|
+
* history for each address with its own pagination state.
|
|
162
|
+
*/
|
|
163
|
+
recentTxHistories(params: AddressHistoryParams[]): Promise<TxHistoryResponse[]>;
|
|
164
|
+
/**
|
|
165
|
+
* Parses a transaction based on the provided transaction ID.
|
|
166
|
+
*
|
|
167
|
+
* @param txid - The unique identifier of the transaction to be parsed.
|
|
168
|
+
* @param options - Optional parsing options. Set includeRaw to true to get extended response with raw transaction data.
|
|
169
|
+
* @returns A promise that resolves to a `ParseTxResponse` or `ParseTxExtendedResponse` containing the parsed transaction details.
|
|
170
|
+
*/
|
|
171
|
+
parseTx(txid: string, options?: ParseOptions): Promise<ParseTxResponse | ParseTxExtendedResponse>;
|
|
172
|
+
/**
|
|
173
|
+
* Parses a transaction from a raw transaction hex string.
|
|
174
|
+
*
|
|
175
|
+
* @param rawTxHex - The raw transaction hex string to be parsed.
|
|
176
|
+
* @param options - Optional parsing options. Set includeRaw to true to get extended response with raw transaction data.
|
|
177
|
+
* @returns A promise that resolves to a `ParseTxResponse` or `ParseTxExtendedResponse` containing the parsed transaction details.
|
|
178
|
+
*/
|
|
179
|
+
parseTxFromRawTx(rawTxHex: string, options?: ParseOptions): Promise<ParseTxResponse | ParseTxExtendedResponse>;
|
|
180
|
+
/**
|
|
181
|
+
* Parses an inscription.
|
|
182
|
+
*
|
|
183
|
+
* @param script - The script to be parsed.
|
|
184
|
+
* @returns A `Inscription` object containing the parsed inscription details.
|
|
185
|
+
*/
|
|
186
|
+
parseInscription(script: Script): Inscription | undefined;
|
|
187
|
+
/**
|
|
188
|
+
* Parses cosigner scripts to extract cosigner public keys and addresses.
|
|
189
|
+
*
|
|
190
|
+
* @param scripts - An array of Script objects to be parsed.
|
|
191
|
+
* @returns An array of `ParsedCosigner` objects containing the parsed cosigner details.
|
|
192
|
+
*/
|
|
193
|
+
parseCosignerScripts(scripts: Script[]): ParsedCosigner[];
|
|
194
|
+
/**
|
|
195
|
+
* Creates a new HDWallet instance for managing hierarchical deterministic wallets.
|
|
196
|
+
* @param mnemonic - The BIP39 mnemonic phrase
|
|
197
|
+
* @param options - Configuration options for the HD wallet
|
|
198
|
+
* @returns A new HDWallet instance
|
|
199
|
+
* @example
|
|
200
|
+
* const mnee = new Mnee(config);
|
|
201
|
+
* const hdWallet = mnee.HDWallet(mnemonic, {
|
|
202
|
+
* derivationPath: "m/44'/236'/0'",
|
|
203
|
+
* cacheSize: 1000
|
|
204
|
+
* });
|
|
205
|
+
*/
|
|
206
|
+
HDWallet(mnemonic: string, options: HDWalletOptions): HDWallet;
|
|
207
|
+
/**
|
|
208
|
+
* Returns a Batch instance for performing batch operations
|
|
209
|
+
* @returns A Batch instance for batch processing
|
|
210
|
+
* @example
|
|
211
|
+
* const batch = mnee.batch();
|
|
212
|
+
* const balances = await batch.getBalances(addresses);
|
|
213
|
+
* const utxos = await batch.getUtxos(addresses);
|
|
214
|
+
*/
|
|
215
|
+
batch(): Batch;
|
|
216
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{Utils as t,LockingScript as e,OP as r,TransactionSignature as s,Hash as n,UnlockingScript as i,Transaction as o,PrivateKey as a,PublicKey as c,Script as u,P2PKH as d,Mnemonic as l,HD as h}from"@bsv/sdk";import*as f from"bip39";function p(){return p=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var r=arguments[e];for(var s in r)({}).hasOwnProperty.call(r,s)&&(t[s]=r[s])}return t},p.apply(null,arguments)}function m(t){const e=new Error(t);return e.stack=void 0,e}class g{lock(s,n){let i=[];if("string"==typeof s){const e=t.fromBase58Check(s);if(0!==e.prefix[0]&&111!==e.prefix[0])throw m("only P2PKH is supported");i=e.data}else i=s;const o=new e;return o.writeOpCode(r.OP_DUP).writeOpCode(r.OP_HASH160).writeBin(i).writeOpCode(r.OP_EQUALVERIFY).writeOpCode(r.OP_CHECKSIGVERIFY).writeBin(n.encode(!0)).writeOpCode(r.OP_CHECKSIG),o}userUnlock(t,e="all",r=!1,o,a){return{sign:async function(c,u){var d,l,h;let f=s.SIGHASH_FORKID;"all"===e&&(f|=s.SIGHASH_ALL),"none"===e&&(f|=s.SIGHASH_NONE),"single"===e&&(f|=s.SIGHASH_SINGLE),r&&(f|=s.SIGHASH_ANYONECANPAY);const p=c.inputs[u],g=c.inputs.filter((t,e)=>e!==u),v=p.sourceTXID?p.sourceTXID:null==(d=p.sourceTransaction)?void 0:d.id("hex");if(!v)throw m("The input sourceTXID or sourceTransaction is required for transaction signing.");if(o||(o=null==(l=p.sourceTransaction)?void 0:l.outputs[p.sourceOutputIndex].satoshis),!o)throw m("The sourceSatoshis or input sourceTransaction is required for transaction signing.");if(a||(a=null==(h=p.sourceTransaction)?void 0:h.outputs[p.sourceOutputIndex].lockingScript),!a)throw m("The lockingScript or input sourceTransaction is required for transaction signing.");const w=s.format({sourceTXID:v,sourceOutputIndex:p.sourceOutputIndex,sourceSatoshis:o,transactionVersion:c.version,otherInputs:g,inputIndex:u,outputs:c.outputs,inputSequence:p.sequence||4294967295,subscript:a,lockTime:c.lockTime,scope:f}),y=t.sign(n.sha256(w)),I=new s(y.r,y.s,f),A=new i;return A.writeBin(I.toChecksigFormat()),A.writeBin(t.toPublicKey().encode(!0)),A},estimateLength:async function(){return 182}}}unlock(t,e,r="all",o=!1,a,c){return{sign:async function(u,d){var l,h,f;let p=s.SIGHASH_FORKID;"all"===r&&(p|=s.SIGHASH_ALL),"none"===r&&(p|=s.SIGHASH_NONE),"single"===r&&(p|=s.SIGHASH_SINGLE),o&&(p|=s.SIGHASH_ANYONECANPAY);const g=u.inputs[d],v=u.inputs.filter((t,e)=>e!==d),w=g.sourceTXID?g.sourceTXID:null==(l=g.sourceTransaction)?void 0:l.id("hex");if(!w)throw m("The input sourceTXID or sourceTransaction is required for transaction signing.");if(a||(a=null==(h=g.sourceTransaction)?void 0:h.outputs[g.sourceOutputIndex].satoshis),!a)throw m("The sourceSatoshis or input sourceTransaction is required for transaction signing.");if(c||(c=null==(f=g.sourceTransaction)?void 0:f.outputs[g.sourceOutputIndex].lockingScript),!c)throw m("The lockingScript or input sourceTransaction is required for transaction signing.");const y=s.format({sourceTXID:w,sourceOutputIndex:g.sourceOutputIndex,sourceSatoshis:a,transactionVersion:u.version,otherInputs:v,inputIndex:d,outputs:u.outputs,inputSequence:g.sequence||4294967295,subscript:c,lockTime:u.lockTime,scope:p}),I=t.sign(n.sha256(y)),A=new s(I.r,I.s,p),x=new i;return x.writeBin(A.toChecksigFormat()),x.writeScript(e),x},estimateLength:async function(){return 182}}}}const v=t=>Buffer.from(t).toString("hex"),w=(t,r,s,n=!1)=>{let i="";if(void 0!==(null==r?void 0:r.dataB64)&&void 0!==(null==r?void 0:r.contentType)){const t=v("ord"),e=Buffer.from(r.dataB64,"base64").toString("hex").trim();if(!e)throw m("Invalid file data");const s=v(r.contentType);if(!s)throw m("Invalid media type");i=`OP_0 OP_IF ${t} OP_1 ${s} OP_0 ${e} OP_ENDIF`}let o=`${i?`${i} ${n?"OP_CODESEPARATOR ":""}`:""}${t.toASM()}`;if(s&&(!s.app||!s.type))throw m("MAP.app and MAP.type are required fields");if(null!=s&&s.app&&null!=s&&s.type){o=`${o?`${o} `:""}OP_RETURN ${v("1PuQa7K62MiKCtssSLKy1kh56WWU7MtUR5")} ${v("SET")}`;for(const[t,e]of Object.entries(s))"cmd"!==t&&(o=`${o} ${v(t)} ${v(e)}`)}return e.fromASM(o)},y=1e-5,I="ae59f3b898ec61acbdb6cc7a245fabeded0c094bf046f35206a3aec60ef88127_0",A="1inHbiwj2jrEcZPiSYnfgJ8FmS1Bmk4Dh",x="833a7720966a2a435db28d967385e8aa7284b6150ebb39482cc5228b73e1703f_0",b="1AZNdbFYBDFTAEgzZMfPzANxyNrpGJZAUY",T=e=>{var s,i;let o;for(let s=0;s<e.chunks.length;s++){var a;const n=e.chunks[s];s>=2&&3===(null==(a=n.data)?void 0:a.length)&&"ord"==t.toUTF8(n.data)&&e.chunks[s-1].op==r.OP_IF&&e.chunks[s-2].op==r.OP_FALSE&&(o=s+1)}if(void 0===o)return;const c={file:{hash:"",size:0,type:""},fields:{}};for(let a=o;a<e.chunks.length;a+=2){var u,d;const o=e.chunks[a];if(o.op==r.OP_ENDIF)break;if(o.op>r.OP_16)return;const l=e.chunks[a+1];if(l.op>r.OP_PUSHDATA4)return;if(null!=(u=o.data)&&u.length)continue;let h=0;switch(o.op>r.OP_PUSHDATA4&&o.op<=r.OP_16?h=o.op-80:null!=(d=o.data)&&d.length&&(h=o.data[0]),h){case 0:if(c.file.size=(null==(s=l.data)?void 0:s.length)||0,null==(i=l.data)||!i.length)break;c.file.hash=t.toBase64(n.sha256(l.data)),c.file.content=l.data;break;case 1:c.file.type=Buffer.from(l.data||[]).toString()}}return c},S=e=>e.map(e=>{const s=e.chunks;for(let e=0;e<=s.length-4;e++){var n,i,o;if(s.length>e+6&&s[0+e].op===r.OP_DUP&&s[1+e].op===r.OP_HASH160&&20===(null==(n=s[2+e].data)?void 0:n.length)&&s[3+e].op===r.OP_EQUALVERIFY&&s[4+e].op===r.OP_CHECKSIGVERIFY&&33===(null==(i=s[5+e].data)?void 0:i.length)&&s[6+e].op===r.OP_CHECKSIG)return{cosigner:t.toHex(s[5+e].data||[]),address:t.toBase58Check(s[2+e].data||[],[0])};if(s[0+e].op===r.OP_DUP&&s[1+e].op===r.OP_HASH160&&20===(null==(o=s[2+e].data)?void 0:o.length)&&s[3+e].op===r.OP_EQUALVERIFY&&s[4+e].op===r.OP_CHECKSIG)return{cosigner:"",address:t.toBase58Check(s[2+e].data||[],[0])}}}).filter(t=>void 0!==t),k=(e,r,s)=>{const n=e.senders.includes(r)?"send":"receive",i=e.height>0?"confirmed":"unconfirmed";if(!e.rawtx)return null;const a=t.toArray(e.rawtx,"base64"),c=t.toHex(a),u=o.fromHex(c).outputs.map(t=>t.lockingScript),d=S(u),l=u.map(T),h=d.map(t=>t.address),f=h.indexOf(s.feeAddress),p=e.senders[0];let m=0;const g=new Map;l.forEach((e,n)=>{var i;const o=null==e||null==(i=e.file)?void 0:i.content;if(!o)return;const a=t.toUTF8(o);if(!a)return;let c;try{c=JSON.parse(a)}catch(t){return void console.error("Failed to parse inscription JSON:",t)}if("bsv-20"!==c.p||c.id!==s.tokenId)return;const u=parseInt(c.amt,10);if(Number.isNaN(u))return;if(f===n&&p===r)return void(m+=u);const d=h[n],l=g.get(d)||0;g.set(d,l+u)});const v=g.get(r)||0;if("send"===n){const t=g.get(p)||0;g.set(p,t-v)}let w=[];w="receive"===n?[{address:p,amount:v}]:Array.from(g.entries()).map(([t,e])=>({address:t,amount:e})).filter(t=>t.address!==r&&t.address!==s.feeAddress&&t.amount>0);const y=w.reduce((t,e)=>t+e.amount,0);return{txid:e.txid,height:e.height,type:n,status:i,amount:y,fee:m,score:e.score,counterparties:w}},$=e=>{try{const r=t.fromBase58Check(e),s=r.prefix[0];if("number"!=typeof s||![0].includes(s))throw m(`Invalid address prefix: ${s}`);if(20!==r.data.length)throw m(`Invalid address payload length: ${r.data.length}`);return!0}catch(t){return!1}},E=t=>{try{return{isValid:!0,privateKey:a.fromWif(t)}}catch(t){if(t instanceof Error){const e=t.message.toLowerCase();if(e.includes("invalid base58 character"))return{isValid:!1,error:"Invalid WIF key: contains invalid characters"};if(e.includes("invalid checksum"))return{isValid:!1,error:"Invalid WIF key: checksum verification failed"};if(e.includes("expected base58 string"))return{isValid:!1,error:"Invalid WIF key: must be a valid base58 encoded string"}}return{isValid:!1,error:"Invalid WIF key provided"}}};class O extends Error{constructor(t){super(t.message),this.code=void 0,this.hostname=void 0,this.originalError=void 0,this.name="NetworkError",this.code=t.code,this.hostname=t.hostname,this.originalError=t.originalError}}function C(t){var e,r,s;if(!t)return!1;const n=["ENOTFOUND","ECONNREFUSED","ETIMEDOUT","ECONNRESET","ENETUNREACH","EHOSTUNREACH","EPIPE","ECONNABORTED"];return!!n.includes(t.code)||!(!t.cause||!n.includes(null==(e=t.cause)?void 0:e.code))||!!(null!=(r=t.message)&&r.includes("fetch failed")||null!=(s=t.message)&&s.includes("getaddrinfo"))}function P(t,e){if(C(t)){const r=function(t){if(t.cause&&t.cause.code){const e=t.cause;let r="Network connection failed";switch(e.code){case"ENOTFOUND":r="Unable to connect to MNEE network. Please check your internet connection.";break;case"ECONNREFUSED":r="Connection refused by MNEE server. The service may be temporarily unavailable.";break;case"ETIMEDOUT":r="Request timed out. Please check your internet connection and try again.";break;case"ECONNRESET":r="Connection was reset. Please try again.";break;case"ENETUNREACH":case"EHOSTUNREACH":r="Network unreachable. Please check your internet connection.";break;default:r=`Network error: ${e.code}. Please check your connection and try again.`}return new O({code:e.code,message:r,hostname:e.hostname,originalError:t})}if(t.code){let e="Network error occurred";switch(t.code){case"ENOTFOUND":e="Unable to connect to MNEE network. Please check your internet connection.";break;case"ECONNREFUSED":e="Connection refused by MNEE server. The service may be temporarily unavailable.";break;case"ETIMEDOUT":e="Request timed out. Please check your internet connection and try again.";break;default:e=`Network error: ${t.code}. Please check your connection and try again.`}return new O({code:t.code,message:e,hostname:t.hostname,originalError:t})}return new O({code:"NETWORK_ERROR",message:"Network error occurred. Please check your internet connection and try again.",originalError:t})}(t);return console.error(`Network error during ${e}: ${r.message}`),r.message}console.error(`Failed to ${e}:`,t)}const N=["parseOptions"];class H{constructor(t){this.service=void 0,this.service=t}async getUtxos(t,e={}){var r=this;if(!Array.isArray(t))throw m("Input must be an array of addresses");const s=[],n=await this.processBatch(t,async function(t){const n=[],i=[];for(const e of t)e&&"string"==typeof e&&""!==e.trim()?/^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$|^bc1[a-z0-9]{39,59}$/.test(e)?n.push(e):(i.push(e),s.push({items:[e],error:{message:`Invalid address format: ${e}`},retryCount:0})):(i.push(e),s.push({items:[e],error:{message:"Invalid address: empty or not a string"},retryCount:0}));if(!e.continueOnError&&i.length>0)throw new Error(s[0].error.message);if(0===n.length)return[];const o=await r.service.getUtxos(n);return t.map(t=>({address:t,utxos:n.includes(t)?o.filter(e=>e.owners.includes(t)):[]}))},e);return p({},n,{errors:[...n.errors,...s],totalErrors:n.errors.length+s.length})}async getBalances(t,e={}){var r=this;if(!Array.isArray(t))throw m("Input must be an array of addresses");return this.processBatch(t,async function(t){return r.service.getBalances(t)},e)}async getTxHistories(t,e={}){var r=this;if(!Array.isArray(t))throw m("Input must be an array of address history parameters");return this.processBatch(t,async function(t){return r.service.getRecentTxHistories(t)},e,t=>t.address)}async parseTx(t,e={}){var r=this;if(!Array.isArray(t))throw m("Input must be an array of transaction IDs");const{parseOptions:s}=e,n=function(t,e){if(null==t)return{};var r={};for(var s in t)if({}.hasOwnProperty.call(t,s)){if(-1!==e.indexOf(s))continue;r[s]=t[s]}return r}(e,N),i=[],o=await this.processBatch(t,async function(t){const e=await Promise.allSettled(t.map(async function(t){if(!t||"string"!=typeof t||""===t.trim())throw new Error("Invalid transaction ID: empty or not a string");if(!/^[a-fA-F0-9]{64}$/.test(t))throw new Error(`Invalid transaction ID format: ${t}`);return{txid:t,parsed:await r.service.parseTx(t,s)}})),o=[];if(e.forEach((e,r)=>{const s=t[r];if("fulfilled"===e.status)o.push(e.value);else{const t=e.reason instanceof Error?e.reason.message:String(e.reason);i.push({items:[s],error:{message:t},retryCount:n.maxRetries||3})}}),!n.continueOnError&&i.length>0)throw new Error(i[0].error.message);return o},n);return p({},o,{errors:[...o.errors,...i],totalErrors:o.errors.length+i.length})}async processBatch(t,e,r,s){var n=this;const{chunkSize:i=20,continueOnError:o=!1,onProgress:a,maxRetries:c=3,retryDelay:u=1e3,requestsPerSecond:d=3}=r,l=i>0?i:20,h=d>0?d:3,f=Math.ceil(1e3/h),p=Math.max(1,Math.floor(h)),m=new M(p,f);if(0===t.length)return{results:[],errors:[],totalProcessed:0,totalErrors:0};const g=[],v=[];let w=0;const y=this.chunkArray(t,l),I=y.length,A=y.map(async function(t){try{const r=await n.processWithRetry(()=>e(t),c,u,m);return g.push(...r),w++,a&&a(w,I,v.length),r}catch(r){if(!o)throw r;const i=[],d=[];for(const r of t)try{const t=await n.processWithRetry(()=>e([r]),c,u,m);t.length>0&&i.push(...t)}catch(t){const e=t instanceof Error?t:new Error(String(t));d.push({item:r,error:e})}if(g.push(...i),d.length>0){const t=d.map(({item:t})=>s?s(t):t),e=d[0].error;v.push({items:t,error:{message:e.message,code:e.code},retryCount:c})}return w++,a&&a(w,I,v.length),i}});return await Promise.all(A),{results:g,errors:v,totalProcessed:w,totalErrors:v.length}}async processWithRetry(t,e,r,s){let n;for(let i=0;i<e;i++)try{return await s.execute(t)}catch(t){n=t,i<e-1&&await this.delay(r*(i+1))}throw n||new Error("Max retries exceeded")}chunkArray(t,e){const r=[],s=Math.max(1,e);for(let e=0;e<t.length;e+=s)r.push(t.slice(e,e+s));return r}delay(t){return new Promise(e=>setTimeout(e,t))}}class M{constructor(t,e){this.maxConcurrent=void 0,this.minDelay=void 0,this.queue=[],this.running=0,this.maxConcurrent=t,this.minDelay=e}async execute(t){await this.waitForSlot();try{this.running++;const e=Date.now(),r=await t(),s=Date.now()-e;return s<this.minDelay&&await this.delay(this.minDelay-s),r}finally{this.running--,this.processQueue()}}waitForSlot(){return this.running<this.maxConcurrent?Promise.resolve():new Promise(t=>{this.queue.push(t)})}processQueue(){if(this.queue.length>0&&this.running<this.maxConcurrent){const t=this.queue.shift();t&&t()}}delay(t){return new Promise(e=>setTimeout(e,t))}}class F{constructor(t){if(this.mneeApiKey=void 0,this.mneeConfig=void 0,this.mneeApi=void 0,"production"!==t.environment&&"sandbox"!==t.environment)throw m('Invalid environment. Must be either "production" or "sandbox"');const e="production"===t.environment;if(""===(null==t?void 0:t.apiKey))throw m("MNEE API key cannot be an empty string");this.mneeApiKey=null!=t&&t.apiKey?t.apiKey:e?"92982ec1c0975f31979da515d46bae9f":"54f1fd1688ba66a58a67675b82feb93e",this.mneeApi=e?"https://proxy-api.mnee.net":"https://sandbox-proxy-api.mnee.net",this.getCosignerConfig().catch(()=>{})}async getCosignerConfig(){try{const t=await fetch(`${this.mneeApi}/v1/config?auth_token=${this.mneeApiKey}`,{method:"GET"});if(401===t.status||403===t.status)throw m("Invalid API key");if(!t.ok)throw m(`HTTP error! status: ${t.status}`);const e=await t.json();return this.mneeConfig=e,e}catch(t){throw C(t)&&P(t,"fetch config"),t}}toAtomicAmount(t){return Math.round(t*10**5)}fromAtomicAmount(t){return t/10**5}async createInscription(t,e,r){const s={p:"bsv-20",op:"transfer",id:r.tokenId,amt:e.toString()};return{lockingScript:w((new g).lock(t,c.fromString(r.approver)),{dataB64:Buffer.from(JSON.stringify(s)).toString("base64"),contentType:"application/bsv-20"}),satoshis:1}}async getUtxos(t,e,r,s){try{if(!t)throw m("Address is required");if("string"==typeof t){if(!$(t))throw m(`Invalid Bitcoin address: ${t}`);const n=[t],i=await fetch(`${this.mneeApi}/v2/utxos?auth_token=${this.mneeApiKey}${void 0!==e?`&page=${e}`:""}${void 0!==r?`&size=${r}`:""}${s?`&order=${s}`:""}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});if(401===i.status||403===i.status)throw m("Invalid API key");if(!i.ok)throw m(`HTTP error! status: ${i.status}`);const o=await i.json(),a=["transfer","deploy+mint"];return o.filter(t=>a.includes(t.data.bsv21.op.toLowerCase()))}if(Array.isArray(t)){const n=t.filter(t=>"string"==typeof t&&$(t));if(0===n.length)throw m("No valid Bitcoin addresses provided");const i=t.filter(t=>"string"!=typeof t||!$(t));i.length>0&&console.warn(`[33m${i.length} invalid bitcoin addresses will be ignored[0m`);const o=await fetch(`${this.mneeApi}/v2/utxos?auth_token=${this.mneeApiKey}${void 0!==e?`&page=${e}`:""}${void 0!==r?`&size=${r}`:""}${s?`&order=${s}`:""}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});if(401===o.status||403===o.status)throw m("Invalid API key");if(!o.ok)throw m(`HTTP error! status: ${o.status}`);const a=await o.json(),c=["transfer","deploy+mint"];return a.filter(t=>c.includes(t.data.bsv21.op.toLowerCase()))}throw m("Invalid input type for address")}catch(t){throw C(t)&&P(t,"fetch UTXOs"),t}}async fetchRawTx(t,e=3){for(let r=0;r<=e;r++)try{const s=await fetch(`${this.mneeApi}/v1/tx/${t}?auth_token=${this.mneeApiKey}`);if(404===s.status)throw m("Transaction not found");if(401===s.status||403===s.status)throw m("Invalid API key");if(429===s.status&&r<e){const t=Math.min(500*Math.pow(2,r),2e3);await new Promise(e=>setTimeout(e,t));continue}if(200!==s.status)throw m(`${s.status} - Failed to fetch rawtx for txid: ${t}`);const{rawtx:n}=await s.json();return o.fromHex(Buffer.from(n,"base64").toString("hex"))}catch(t){if(r===e)return void(C(t)&&P(t,"fetch transaction"));await new Promise(t=>setTimeout(t,200))}}async getSignatures(e,r){try{const i=65;let a;switch(e.format){case"beef":a=o.fromHexBEEF(e.rawtx);break;case"ef":a=o.fromHexEF(e.rawtx);break;default:a=o.fromHex(e.rawtx)}const c=e.sigRequests.flatMap(e=>[r].map(r=>{const o=s.format({sourceTXID:e.prevTxid,sourceOutputIndex:e.outputIndex,sourceSatoshis:e.satoshis,transactionVersion:a.version,otherInputs:a.inputs.filter((t,r)=>r!==e.inputIndex),inputIndex:e.inputIndex,outputs:a.outputs,inputSequence:a.inputs[e.inputIndex].sequence||0,subscript:e.script?u.fromHex(e.script):(new d).lock(r.toPublicKey().toAddress()),lockTime:a.lockTime,scope:e.sigHashType||i}),c=r.sign(n.sha256(o)),l=new s(c.r,c.s,e.sigHashType||i);return{sig:t.toHex(l.toChecksigFormat()),pubKey:r.toPublicKey().toString(),inputIndex:e.inputIndex,sigHashType:e.sigHashType||i,csIdx:e.csIdx}}));return Promise.resolve({sigResponses:c})}catch(t){var i;return C(t)&&P(t,"get signatures"),{error:{message:null!=(i=t.message)?i:"unknown",cause:t.cause}}}}async getEnoughUtxos(t,e){const r=this.mneeConfig||await this.getCosignerConfig();if(!r)throw m("Config not fetched");const s=r.fees.find(t=>e>=t.min&&e<=t.max);if(!s)throw m("Fee not found");const n=s.fee,i=e+n,o=await this.getBalance(t);if(o.amount<i)throw m(`Insufficient MNEE balance. Max transfer amount: ${this.fromAtomicAmount(o.amount-n)}`);let a=1,c=[],u=0;for(;u<i;){const e=await this.getUtxos(t,a,25);if(0===e.length)throw m(`Insufficient MNEE balance. Max transfer amount: ${this.fromAtomicAmount(u-n)}`);if(c.push(...e),u=c.reduce((t,e)=>t+e.data.bsv21.amt,0),u>=i)break;a++}c.sort((t,e)=>e.data.bsv21.amt-t.data.bsv21.amt);let d=[],l=0;for(const t of c)if(d.push(t),l+=t.data.bsv21.amt,l>=i)break;return d}async getAllUtxos(t){let e=1,r=[];for(;;){const s=await this.getUtxos(t,e,100);if(0===s.length)break;r.push(...s),e++}return r}async transfer(t,e,r){try{var s;const n=this.mneeConfig||await this.getCosignerConfig();if(!n)throw m("Config not fetched");const{isValid:a,totalAmount:c,privateKey:u,error:d}=((t,e)=>{const{isValid:r,error:s,privateKey:n}=E(e);if(0===t.length)return{isValid:!1,error:"Empty transfer options provided. Please provide at least one recipient."};if(!r)return{isValid:!1,error:s||"Invalid WIF key provided"};if(!n)return{isValid:!1,error:"Private key not found"};let i=0;for(const e of t){if(!$(e.address))return{isValid:!1,error:`Invalid recipient address: ${e.address}`};if("number"!=typeof e.amount||isNaN(e.amount)||!isFinite(e.amount))return{isValid:!1,error:`Invalid amount for ${e.address}: amount must be a valid number`};if(e.amount<y)return{isValid:!1,error:`Invalid amount for ${e.address}: minimum transfer amount is 0.00001 MNEE`};i+=e.amount}return i<=0?{isValid:!1,error:"Invalid amount: total must be greater than 0"}:{isValid:!0,totalAmount:i,privateKey:n}})(t,e);if(!a)throw m(d||"Invalid transfer options");if(!u)throw m("Private key not found");if(!c)throw m("Invalid amount");const l=this.toAtomicAmount(c),h=u.toAddress(),f=await this.getEnoughUtxos(h,l),p=void 0!==t.find(t=>t.address===n.burnAddress)?0:null==(s=n.fees.find(t=>l>=t.min&&l<=t.max))?void 0:s.fee;if(void 0===p)throw m("Fee ranges inadequate");const g=new o(1,[],[],0);let v=0,w="";for(;v<l+p;){const t=f.shift();if(!t){const t=await this.getBalance(h);throw m("Insufficient MNEE balance. Max transfer amount is "+this.fromAtomicAmount(t.amount-p))}const e=await this.fetchRawTx(t.txid);if(!e)throw m(`Failed to fetch source transaction: ${t.txid}_${t.vout}`);w=w||t.owners[0],g.addInput({sourceTXID:t.txid,sourceOutputIndex:t.vout,sourceTransaction:e,unlockingScript:new i}),v+=t.data.bsv21.amt}for(const e of t)g.addOutput(await this.createInscription(e.address,this.toAtomicAmount(e.amount),n));p>0&&g.addOutput(await this.createInscription(n.feeAddress,p,n));const I=v-l-p;I>0&&g.addOutput(await this.createInscription(w,I,n));const A=new Map;for(let t=0;t<g.inputs.length;t++)A.set(t,u);const x=await this.signAllInputs(g,A);if(x.error)throw m(x.error);const b=g.toHex();if(!1===(null==r?void 0:r.broadcast))return{rawtx:b};const{ticketId:T}=await this.submitRawTx(b,r);if(!T)throw m("Failed to broadcast transaction");return{ticketId:T}}catch(t){throw C(t)&&P(t,"transfer tokens"),t}}async submitRawTx(e,r={broadcast:!0,callbackUrl:void 0}){try{var s,n,i,a;if(!1!==(null==(s=r)?void 0:s.broadcast)&&(r=p({},r,{broadcast:!0})),null!=(n=r)&&n.callbackUrl&&!1===(null==(i=r)?void 0:i.broadcast))throw m("Callback URL cannot be provided when broadcast is false");if(!e)throw m("Raw transaction is required");const c=o.fromHex(e);if(null==(a=r)||!a.broadcast)return{rawtx:c.toHex()};const u=t.toBase64(c.toBinary()),d=JSON.stringify(r?{rawtx:u,callback_url:r.callbackUrl}:{rawtx:u}),l=await fetch(`${this.mneeApi}/v2/transfer?auth_token=${this.mneeApiKey}`,{method:"POST",headers:{"Content-Type":"application/json"},body:d});if(!l.ok)throw m(`Failed to submit transaction: ${l.status}`);return{ticketId:await l.text()}}catch(t){throw C(t)&&P(t,"submit raw transaction"),t}}async getTxStatus(t){try{if(!t)throw m("Ticket ID is required");const e=await fetch(`${this.mneeApi}/v2/ticket?ticketID=${t}&auth_token=${this.mneeApiKey}`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!e.ok)throw m(`Failed to get transaction status: ${e.status}`);return await e.json()}catch(t){throw C(t)&&P(t,"get transaction status"),t}}async getBalance(t){if(!$(t))throw m(`Invalid Bitcoin address: ${t}`);try{if(!this.mneeConfig&&!await this.getCosignerConfig())throw m("Config not fetched");const e=await fetch(`${this.mneeApi}/v2/balance?auth_token=${this.mneeApiKey}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify([t])});if(!e.ok)throw m(`Failed to get transaction status: ${e.status}`);const r=await e.json();return r&&0!==r.length?{address:r[0].address,amount:r[0].amt,decimalAmount:r[0].precised}:{address:t,amount:0,decimalAmount:0}}catch(t){throw C(t)&&P(t,"fetch balance"),t}}async getBalances(t){if(!Array.isArray(t))throw m("Addresses must be an array");const e=t.filter(t=>$(t));if(0===e.length)throw m("You must pass at least 1 valid address");const r=t.length-e.length;r>0&&console.warn(`[33m${r} invalid bitcoin addresses will be ignored[0m`);try{if(!this.mneeConfig&&!await this.getCosignerConfig())throw m("Config not fetched");const t=await fetch(`${this.mneeApi}/v2/balance?auth_token=${this.mneeApiKey}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!t.ok)throw m(`Failed to get transaction status: ${t.status}`);const r=await t.json();if(!r||0===r.length)return e.map(t=>({address:t,amount:0,decimalAmount:0}));const s=new Map;return r.forEach(t=>{s.set(t.address,{address:t.address,amount:t.amt,decimalAmount:t.precised})}),e.map(t=>s.has(t)?s.get(t):{address:t,amount:0,decimalAmount:0})}catch(t){throw C(t)&&P(t,"fetch balances"),t}}processMneeValidation(e,r,s){try{const n=e.id("hex")===r.tokenId.split("_")[0],i=e.outputs.map(t=>t.lockingScript),o=S(i),a=e.outputs.map((e,r)=>{var s;const n=o[r],i=T(e.lockingScript);let a=null;if(null!=i&&null!=(s=i.file)&&s.content)try{const e=t.toUTF8(i.file.content);e&&(a=JSON.parse(e))}catch(t){}return{index:r,address:null==n?void 0:n.address,cosigner:null==n?void 0:n.cosigner,inscription:a}}),c=a.some(t=>t.cosigner===r.approver);if(a.find(t=>""!==t.cosigner&&t.cosigner!==r.approver))throw m("Invalid cosigner detected");const u=a.filter(t=>{if(!t.inscription)return!1;const e=t.inscription;if("bsv-20"!==e.p)return!1;if(!n&&e.id!==r.tokenId)throw m(`Invalid token ID: ${e.id}`);const s=parseInt(e.amt,10);if(isNaN(s)||s<=0)throw m(`Invalid MNEE amount: ${e.amt}`);return!0});if(0===u.length)throw m("No valid MNEE inscriptions found in transaction");const d=new Set(u.map(t=>t.inscription.op)),l=d.has("burn"),h=u.some(t=>{var e;return"transfer"===t.inscription.op&&"redeem"===(null==(e=t.inscription.metadata)?void 0:e.action)}),f=h&&a.some(t=>t.address===b||t.address===A);if((d.has("transfer")&&!h||l||h&&!f)&&!c)throw m("Cosigner not found in transaction with transfer/burn/redeem operation");const p=u.filter(t=>{const e=t.inscription;return"transfer"===e.op||"burn"===e.op||"deploy+mint"===e.op});if(s){const t=[...p];for(const e of s){const r=t.findIndex(t=>t.address===e.address&&t.inscription.amt===this.toAtomicAmount(e.amount).toString());if(-1===r)throw m(`No matching output found for ${e.address} with amount ${e.amount}`);t.splice(r,1)}}return!0}catch(t){return C(t)&&P(t,"validate Mnee transaction"),!1}}async validateMneeTx(t,e){try{const r=this.mneeConfig||await this.getCosignerConfig();if(!r)throw m("Config not fetched");const s=o.fromHex(t);if(!this.processMneeValidation(s,r,e))return!1;if(s.id("hex")!==r.tokenId.split("_")[0]){const t=await this.processTransactionInputs(s,r),e=this.processTransactionOutputs(s,r);if(t.total!==e.total)return!1}return!0}catch(t){return C(t)&&P(t,"validate Mnee transaction"),!1}}async getMneeSyncs(t,e,r,s){try{const n=Array.isArray(t)?t:[t],i=await fetch(`${this.mneeApi}/v1/sync?auth_token=${this.mneeApiKey}${e?`&from=${e}`:""}${r?`&limit=${r}`:""}${s?`&order=${s}`:""}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});if(401===i.status||403===i.status)throw m("Invalid API key");if(!i.ok)throw m(`HTTP error! status: ${i.status}`);const o=await i.json();return n.map(t=>{const e=o.filter(e=>e.senders.includes(t)||e.receivers.includes(t));return{address:t,syncs:e}})}catch(t){throw C(t)&&P(t,"fetch syncs"),t}}async getRecentTxHistory(t,e,r,s){if(!$(t))throw m(`Invalid Bitcoin address: ${t}`);if(void 0!==e&&("number"!=typeof e||e<0||!Number.isFinite(e)))throw m(`Invalid fromScore: ${e}. Must be a positive number or 0`);if(void 0!==r&&("number"!=typeof r||r<=0||!Number.isInteger(r)))throw m(`Invalid limit: ${r}. Must be a positive integer`);if(void 0!==s&&"asc"!==s&&"desc"!==s)throw m(`Invalid order: ${s}. Must be 'asc' or 'desc'`);try{const n=this.mneeConfig||await this.getCosignerConfig();if(!n)throw m("Config not fetched");const i=await this.getMneeSyncs(t,e,r,s),{syncs:o}=i[0];if(!o||0===o.length)return{address:t,history:[],nextScore:e||0};const a=[];for(const e of o){const r=k(e,t,n);r&&a.push(r)}const c=a.length>0?a[a.length-1].score:e||0;return r&&a.length>r?{address:t,history:a.slice(0,r),nextScore:c}:{address:t,history:a,nextScore:c}}catch(t){throw C(t)&&P(t,"fetch transaction history"),t}}async getRecentTxHistories(t){var e=this;if(!Array.isArray(t))throw m("Parameters must be an array");if(0===t.length)throw m("You must pass at least 1 address parameter");const r=t.filter(t=>t&&t.address&&$(t.address));if(0===r.length)throw m("You must pass at least 1 valid address");const s=t.length-r.length;s>0&&console.warn(`[33m${s} invalid bitcoin addresses will be ignored[0m`);for(const t of r){if(void 0!==t.fromScore&&("number"!=typeof t.fromScore||t.fromScore<0||!Number.isFinite(t.fromScore)))throw m(`Invalid fromScore for address ${t.address}: ${t.fromScore}. Must be a positive number or 0`);if(void 0!==t.limit&&("number"!=typeof t.limit||t.limit<=0||!Number.isInteger(t.limit)))throw m(`Invalid limit for address ${t.address}: ${t.limit}. Must be a positive integer`);if(void 0!==t.order&&"asc"!==t.order&&"desc"!==t.order)throw m(`Invalid order for address ${t.address}: ${t.order}. Must be 'asc' or 'desc'`)}try{const t=this.mneeConfig||await this.getCosignerConfig();if(!t)throw m("Config not fetched");const s={};r.forEach(t=>{const e=`${t.fromScore||0}:${t.limit||100}:${t.order||"default"}`;s[e]||(s[e]=[]),s[e].push(t)});const n=Object.entries(s).map(async function([r,s]){const[n,i,o]=r.split(":"),a=Number(n),c=Number(i),u="default"===o?void 0:o,d=s.map(t=>t.address);return(await e.getMneeSyncs(d,a,c,u)).map(({address:e,syncs:r})=>{const n=s.find(t=>t.address===e);if(!r||0===r.length)return{address:e,history:[],nextScore:(null==n?void 0:n.fromScore)||0};const i=[],o=new Set;for(const s of r){const r=k(s,e,t);r&&!o.has(r.txid)&&(o.add(r.txid),i.push(r))}const a=i.length>0?i[i.length-1].score:(null==n?void 0:n.fromScore)||0,c=null==n?void 0:n.limit;return c&&i.length>c?{address:e,history:i.slice(0,c),nextScore:a}:{address:e,history:i,nextScore:a}})});return(await Promise.all(n)).flat()}catch(t){throw C(t)&&P(t,"fetch transaction histories"),t}}parseInscriptionData(e){try{var r;const s=T(e),n=null==s||null==(r=s.file)?void 0:r.content;if(!n)return null;const i=t.toUTF8(n);return i?JSON.parse(i):null}catch(t){return C(t)&&P(t,"parse inscription data"),null}}determineEnvironment(t,e,r,s){return t===I.split("_")[0]?"production":t===x.split("_")[0]?"sandbox":e===I&&"020a177d6a5e6f3a8689acd2e313bd1cf0dcf5a243d1cc67b7218602aee9e04b2f"===r?"production":e===x&&"02bed35e894cc41cc9879b4002ad03d33533b615c1b476068c8dd6822a09f93f6c"===r?"sandbox":""===r&&s===A?"production":"sandbox"}determineTransactionType(t,e,r,s,n){return"burn"===t?"burn":"deploy+mint"===t||e===s?r===n.split("_")[0]?"deploy":"mint":e===A||e===b?"mint":"transfer"}async processTransactionInputs(t,e){var r=this;const s=t.id("hex"),n=new Array(t.inputs.length);let i,o,a=BigInt(0);const c=new M(3,334),u=t.inputs.map(async function(t,e){if(!t.sourceTXID)return{index:e,sourceTx:null};try{return{index:e,sourceTx:await c.execute(()=>r.fetchRawTx(t.sourceTXID))}}catch(t){return C(t)&&P(t,"fetch source transaction"),{index:e,sourceTx:null}}}),d=await Promise.all(u);for(const{index:r,sourceTx:c}of d){const u=t.inputs[r];if(!c||!u.sourceTXID){n[r]={address:void 0,amount:0,satoshis:0,inscription:null,cosigner:void 0};continue}const d=c.outputs[u.sourceOutputIndex],l=S([d.lockingScript])[0],h=this.parseInscriptionData(d.lockingScript),f={address:null==l?void 0:l.address,amount:h?parseInt(h.amt):0,satoshis:Number(d.satoshis),inscription:h,cosigner:l};n[r]=f,h&&l&&(a+=BigInt(h.amt),i||(i=this.determineEnvironment(s,h.id,l.cosigner||"",l.address||"")),o||(o=this.determineTransactionType(h.op,l.address||"",s,e.mintAddress,e.tokenId)))}return{inputs:n,total:a,environment:i,type:o}}processTransactionOutputs(t,e){const r=t.id("hex"),s=[];let n,i,o=BigInt(0);for(let a=0;a<t.outputs.length;a++){const c=t.outputs[a],u=S([c.lockingScript])[0],d=this.parseInscriptionData(c.lockingScript),l={address:null==u?void 0:u.address,amount:d?parseInt(d.amt):0,satoshis:Number(c.satoshis),inscription:d,cosigner:u};if(s.push(l),d&&u){o+=BigInt(d.amt),n=this.determineEnvironment(r,d.id,u.cosigner||"",u.address||"");const t=this.determineTransactionType(d.op,u.address||"",r,e.mintAddress,e.tokenId);"burn"===t||"deploy"===t?i=t:i||(i=t)}}return{outputs:s,total:o,environment:n,type:i}}validateTransaction(t,e,r,s,n){return!!this.processMneeValidation(e,t)&&("deploy"===r||s===n)}buildParseResponse(t,e,r,s,n,i,o,a){const c={txid:t,environment:e,type:r,inputs:s.inputs.filter(t=>t.inscription&&t.address).map(t=>({address:t.address,amount:t.amount})),outputs:n.outputs.filter(t=>t.inscription&&t.address).map(t=>({address:t.address,amount:t.amount})),isValid:i,inputTotal:s.total.toString(),outputTotal:n.total.toString()};return null!=a&&a.includeRaw?p({},c,{raw:{txHex:o.toHex(),inputs:o.inputs.map((t,e)=>{var r;const n=s.inputs[e];return{txid:t.sourceTXID||"",vout:t.sourceOutputIndex,scriptSig:(null==(r=t.unlockingScript)?void 0:r.toHex())||"",sequence:t.sequence||4294967295,address:null==n?void 0:n.address,satoshis:(null==n?void 0:n.satoshis)||0,tokenData:null!=n&&n.inscription?{amount:n.amount}:void 0}}),outputs:o.outputs.map((t,e)=>{const r=n.outputs[e];return{value:Number(t.satoshis),scriptPubKey:t.lockingScript.toHex(),address:null==r?void 0:r.address,tokenData:null!=r&&r.inscription?{amount:r.amount}:void 0}})}}):c}async parseTransaction(t,e,r){const s=t.id("hex"),n=await this.processTransactionInputs(t,e),i=this.processTransactionOutputs(t,e),o=i.environment||n.environment||"sandbox";let a=i.type||n.type||"transfer";"transfer"===a&&n.inputs.some(t=>t.inscription&&(t.address===A||t.address===b))&&(a="mint"),"transfer"!==a&&"mint"!==a||i.outputs.some(t=>{var e;return"redeem"===(null==(e=t.inscription)||null==(e=e.metadata)?void 0:e.action)})&&(a="redeem"),0===n.inputs.filter(t=>t.inscription).length&&n.inputs.length>0&&(a="deploy");const c=this.validateTransaction(e,t,a,n.total,i.total);return this.buildParseResponse(s,o,a,n,i,c,t,r)}async parseTx(t,e){if(!t||"string"!=typeof t||""===t.trim()||!/^[a-fA-F0-9]{64}$/.test(t))throw m("A valid transaction ID is required");const r=this.mneeConfig||await this.getCosignerConfig();if(!r)throw m("Config not fetched");const s=await this.fetchRawTx(t);if(!s)throw m("Failed to fetch transaction");return await this.parseTransaction(s,r,e)}async parseTxFromRawTx(t,e){if(!t||"string"!=typeof t||""===t.trim())throw m("A valid raw transaction is required");if(!(t=>{try{return o.fromHex(t),!0}catch(t){return!1}})(t))throw m("Invalid raw transaction hex");const r=o.fromHex(t),s=this.mneeConfig||await this.getCosignerConfig();if(!s)throw m("Config not fetched");return await this.parseTransaction(r,s,e)}parseInscription(t){return T(t)}parseCosignerScripts(t){return S(t)}validateUniqueInputs(t){const e=new Set;for(const r of t){const t=`${r.txid}:${r.vout}`;if(e.has(t))return{error:`Duplicate input detected: ${t}. Each UTXO can only be spent once.`};e.add(t)}return{}}async addInputsToTransaction(t,e,r){let s=0;for(let n=0;n<e.length;n++){const o=e[n],c=await this.fetchRawTx(o.txid);if(!c)return{tokensIn:0,error:`Failed to fetch source transaction: ${o.txid}_${o.vout}`};const u=c.outputs[o.vout];if(!u)return{tokensIn:0,error:`Output ${o.vout} not found in transaction ${o.txid}`};const d=this.parseInscriptionData(u.lockingScript);if(!d)return{tokensIn:0,error:`No inscription found in output ${o.txid}:${o.vout}`};s+=parseInt(d.amt),r.set(n,a.fromWif(o.wif)),t.addInput({sourceTXID:o.txid,sourceOutputIndex:o.vout,sourceTransaction:c,unlockingScript:new i})}return{tokensIn:s}}calculateTransferMultiFee(t,e,r,s,n,i){let o=0,a=-1;for(;o!==a;){var c;a=o;const u=t-e-o;let d=0;if(u>0)if("string"==typeof r)s.has(r)||(d=u);else if(Array.isArray(r))for(const t of r){const e=this.toAtomicAmount(t.amount);s.has(t.address)||(d+=e)}else d=0;const l=e+d,h=void 0!==i.find(t=>t.address===n.burnAddress)?0:null==(c=n.fees.find(t=>l>=t.min&&l<=t.max))?void 0:c.fee;if(void 0===h)return{fee:0,error:"Fee ranges inadequate"};o=h}return{fee:o}}async addChangeOutputs(t,e,r,s,n,i,o,a){if(e<=0)return{};if("string"==typeof r)t.addOutput(await this.createInscription(r,e,n));else if(Array.isArray(r)){if(0===r.length)return{error:"Change address array cannot be empty. Provide at least one change output or use a single address string."};const s=r.map(t=>({address:t.address,amount:this.toAtomicAmount(t.amount)})),c=s.reduce((t,e)=>t+e.amount,0);if(c!==e){const t=this.fromAtomicAmount(e),r=this.fromAtomicAmount(c);return{error:`Change amounts must sum to ${t} (${e} atomic units). Total inputs: ${this.fromAtomicAmount(i)} - total outputs: ${this.fromAtomicAmount(o)} - fee: ${this.fromAtomicAmount(a)} = ${t}. Your change outputs sum to ${r} (${c} atomic units).`}}for(const t of r)if(t.amount<=0)return{error:`Invalid change amount: ${t.amount}. Must be positive.`};for(const e of s)t.addOutput(await this.createInscription(e.address,e.amount,n))}else{const r=s.get(0).toAddress();t.addOutput(await this.createInscription(r,e,n))}return{}}async signAllInputs(e,r){const n=e.inputs.map((t,e)=>{var n,i;if(!t.sourceTXID)throw m("Source TXID is undefined");return{prevTxid:t.sourceTXID,outputIndex:t.sourceOutputIndex,inputIndex:e,address:r.get(e).toAddress(),script:null==(n=t.sourceTransaction)?void 0:n.outputs[t.sourceOutputIndex].lockingScript.toHex(),satoshis:(null==(i=t.sourceTransaction)?void 0:i.outputs[t.sourceOutputIndex].satoshis)||1,sigHashType:s.SIGHASH_ALL|s.SIGHASH_ANYONECANPAY|s.SIGHASH_FORKID}}),i=e.toHex(),o=[];for(const[t,e]of r.entries()){const r=n[t],s=await this.getSignatures({rawtx:i,sigRequests:[r]},e);if(null==s||!s.sigResponses)return{error:`Failed to get signatures for input ${t}`};o.push(...s.sigResponses)}for(const r of o)e.inputs[r.inputIndex].unlockingScript=(new u).writeBin(t.toArray(r.sig,"hex")).writeBin(t.toArray(r.pubKey,"hex"));return{}}validateTokenConservation(t,e){let r=0;for(let e=0;e<t.outputs.length;e++){const s=this.parseInscriptionData(t.outputs[e].lockingScript);s&&(r+=parseInt(s.amt))}return e!==r?{error:`Token conservation violation! Inputs (${this.fromAtomicAmount(e)}) do not equal outputs (${this.fromAtomicAmount(r)}). This would ${e>r?"burn":"create"} ${this.fromAtomicAmount(Math.abs(e-r))} tokens.`}:{}}async transferMulti(t,e){try{const r=this.mneeConfig||await this.getCosignerConfig();if(!r)throw m("Config not fetched");const{isValid:s,error:n}=(t=>{for(const e of t.recipients){if(!e.address||!e.amount)return{isValid:!1,error:`Invalid recipient: ${JSON.stringify(e)}. Missing required fields: address, amount`};if("number"!=typeof e.amount||isNaN(e.amount)||!isFinite(e.amount))return{isValid:!1,error:`Invalid amount for ${e.address}: amount must be a valid number`};if(e.amount<y)return{isValid:!1,error:`Invalid amount for ${e.address}: minimum transfer amount is 0.00001 MNEE`};if(!$(e.address))return{isValid:!1,error:`Invalid recipient address: ${e.address}`}}for(const e of t.inputs){if(!e.txid||"number"!=typeof e.vout||!e.wif)return{isValid:!1,error:`Invalid input: ${JSON.stringify(e)}. Missing required fields: txid, vout, wif`};const t=E(e.wif);if(!t.isValid)return{isValid:!1,error:`Invalid WIF key: ${e.wif} for input ${e.txid}:${e.vout}`};const r=t.privateKey.toAddress();if(!$(r))return{isValid:!1,error:`Invalid input address: ${r}`}}if(t.changeAddress&&Array.isArray(t.changeAddress))for(const e of t.changeAddress){if(e.amount<y)return{isValid:!1,error:`Invalid amount for ${e.address}: minimum transfer amount is 0.00001 MNEE`};if(!$(e.address))return{isValid:!1,error:`Invalid change address: ${e.address}`}}return{isValid:!0}})(t);if(!s)throw m(n||"Invalid transfer options");const i=t.recipients.reduce((t,e)=>t+e.amount,0);if(i<=0)throw m("Invalid amount");const c=this.toAtomicAmount(i),u=this.validateUniqueInputs(t.inputs);if(u.error)throw m(u.error);const d=new o(1,[],[],0),l=new Map,h=await this.addInputsToTransaction(d,t.inputs,l);if(h.error)throw m(h.error);const f=h.tokensIn,p=new Set;for(let e=0;e<t.inputs.length;e++){const r=a.fromWif(t.inputs[e].wif);p.add(r.toAddress())}const g=this.calculateTransferMultiFee(f,c,t.changeAddress,p,r,t.recipients);if(g.error)throw m(g.error);const v=g.fee;if(f<c+v)throw m(`Insufficient tokens. Have: ${this.fromAtomicAmount(f)}, Need: ${this.fromAtomicAmount(c+v)} (including fee: ${this.fromAtomicAmount(v)})`);for(const e of t.recipients)d.addOutput(await this.createInscription(e.address,this.toAtomicAmount(e.amount),r));v>0&&d.addOutput(await this.createInscription(r.feeAddress,v,r));const w=f-c-v,I=await this.addChangeOutputs(d,w,t.changeAddress,l,r,f,c,v);if(I.error)throw m(I.error);const A=await this.signAllInputs(d,l);if(A.error)throw m(A.error);const x=this.validateTokenConservation(d,f);if(x.error)throw m(x.error);const b=d.toHex();if(null==e||!e.broadcast)return{rawtx:b};const{ticketId:T}=await this.submitRawTx(b,e);if(!T)throw m("Failed to broadcast transaction");return{ticketId:T}}catch(t){throw C(t)&&P(t,"multi-source transfer"),t}}}class D{constructor(t,e){if(this.masterKey=void 0,this.derivationPath=void 0,this.cacheSize=void 0,this.cache=void 0,!f.validateMnemonic(t))throw m("Invalid mnemonic phrase");const r=l.fromString(t).toSeed();this.masterKey=h.fromSeed(r),this.derivationPath=e.derivationPath,this.cacheSize=e.cacheSize||1e3,this.cache=new Map}static generateMnemonic(){return f.generateMnemonic()}static isValidMnemonic(t){return f.validateMnemonic(t)}deriveAddress(t,e=!1){const r=`${this.derivationPath}/${e?1:0}/${t}`;if(this.cache.has(r))return this.cache.get(r);const s=this.masterKey.derive(r).privKey;if(!s)throw m(`Failed to derive private key for path: ${r}`);const n={address:s.toAddress(),privateKey:s.toWif(),path:r};return this.cache.size<this.cacheSize&&this.cache.set(r,n),n}async deriveAddresses(t,e,r=!1){const s=[];for(let n=0;n<e;n++){const e=this.deriveAddress(t+n,r);s.push(e)}return s}getPrivateKeysForAddresses(t,e){const r=(null==e?void 0:e.maxScanReceive)||1e4,s=(null==e?void 0:e.maxScanChange)||1e4,n=(null==e?void 0:e.scanStrategy)||"parallel",i={},o={},a=new Set(t);for(const[t,e]of this.cache)a.has(e.address)&&(i[e.address]=e.privateKey,o[e.address]=e.path,a.delete(e.address));if(0===a.size)return{privateKeys:i,paths:o};if("sequential"===n){for(let t=0;t<r&&a.size>0;t++){const e=this.deriveAddress(t,!1);a.has(e.address)&&(i[e.address]=e.privateKey,o[e.address]=e.path,a.delete(e.address))}for(let t=0;t<s&&a.size>0;t++){const e=this.deriveAddress(t,!0);a.has(e.address)&&(i[e.address]=e.privateKey,o[e.address]=e.path,a.delete(e.address))}}else{const t=Math.max(r,s);for(let e=0;e<t&&a.size>0;e++){if(e<r){const t=this.deriveAddress(e,!1);a.has(t.address)&&(i[t.address]=t.privateKey,o[t.address]=t.path,a.delete(t.address))}if(e<s){const t=this.deriveAddress(e,!0);a.has(t.address)&&(i[t.address]=t.privateKey,o[t.address]=t.path,a.delete(t.address))}}}if(a.size>0){const t=Array.from(a);throw m(`Could not find private keys for ${t.length} address(es): ${t.join(", ")}. Scanned up to index ${r} for receive addresses and ${s} for change addresses.`)}return{privateKeys:i,paths:o}}getPrivateKeys(t,e){return this.getPrivateKeysForAddresses(t,e).privateKeys}async scanAddressesWithGapLimit(t,e){const r=(null==e?void 0:e.gapLimit)||20,s=!1!==(null==e?void 0:e.scanChange),n=(null==e?void 0:e.maxScan)||1e4,i={receive:[],change:[]};let o=0;for(let e=0;e<n&&o<r;e++){const r=this.deriveAddress(e,!1);await t(r.address)?(i.receive.push(r),o=0):o++}if(s){o=0;for(let e=0;e<n&&o<r;e++){const r=this.deriveAddress(e,!0);await t(r.address)?(i.change.push(r),o=0):o++}}return i}clearCache(){this.cache.clear()}getCacheSize(){return this.cache.size}}class _{constructor(t){this.service=void 0,this._batch=void 0,this.service=new F(t)}async validateMneeTx(t,e){return this.service.validateMneeTx(t,e)}toAtomicAmount(t){return this.service.toAtomicAmount(t)}fromAtomicAmount(t){return this.service.fromAtomicAmount(t)}async config(){return this.service.getCosignerConfig()}async balance(t){return this.service.getBalance(t)}async balances(t){return this.service.getBalances(t)}async getUtxos(t,e,r,s){return this.service.getUtxos(t,e,r,s)}async getEnoughUtxos(t,e){return this.service.getEnoughUtxos(t,e)}async getAllUtxos(t){return this.service.getAllUtxos(t)}async transfer(t,e,r){return this.service.transfer(t,e,r)}async transferMulti(t,e){return this.service.transferMulti(t,e)}async submitRawTx(t,e){return this.service.submitRawTx(t,e)}async getTxStatus(t){return this.service.getTxStatus(t)}async recentTxHistory(t,e,r,s){return this.service.getRecentTxHistory(t,e,r,s)}async recentTxHistories(t){return this.service.getRecentTxHistories(t)}async parseTx(t,e){return this.service.parseTx(t,e)}async parseTxFromRawTx(t,e){return this.service.parseTxFromRawTx(t,e)}parseInscription(t){return this.service.parseInscription(t)}parseCosignerScripts(t){return this.service.parseCosignerScripts(t)}HDWallet(t,e){return new D(t,e)}batch(){return this._batch||(this._batch=new H(this.service)),this._batch}}_.HDWallet=D;export{_ as default};
|
|
2
|
+
//# sourceMappingURL=index.modern.js.map
|