@avalabs/core-wallets-sdk 3.1.0-alpha.1 → 3.1.0-alpha.11

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.
Files changed (27) hide show
  1. package/dist/index.d.ts +163 -39
  2. package/dist/index.js +1 -1
  3. package/esm/Avalanche/models.d.ts +2 -2
  4. package/esm/Avalanche/providers/AbstractProvider.d.ts +9 -2
  5. package/esm/Avalanche/providers/AbstractProvider.js +1 -1
  6. package/esm/Avalanche/providers/JsonRpcProvider.d.ts +4 -3
  7. package/esm/Avalanche/providers/JsonRpcProvider.js +1 -1
  8. package/esm/Avalanche/providers/constants.js +1 -1
  9. package/esm/Avalanche/providers/platformFeeConfig.js +1 -0
  10. package/esm/Avalanche/utils/convertGlacierUtxo.d.ts +2 -2
  11. package/esm/Avalanche/utils/getPchainUnixNow.js +1 -1
  12. package/esm/Avalanche/utils/getUtxosByTxFromGlacier.d.ts +3 -1
  13. package/esm/Avalanche/utils/getUtxosByTxFromGlacier.js +1 -1
  14. package/esm/Avalanche/utils/parseAvalancheTx.js +1 -1
  15. package/esm/Avalanche/utils/parsers/parseAddPermissionlessDelegatorTx.js +1 -1
  16. package/esm/Avalanche/utils/parsers/parseAddPermissionlessValidatorTx.js +1 -1
  17. package/esm/Avalanche/utils/sortUTXOs.d.ts +5 -4
  18. package/esm/Avalanche/utils/txSizeLimits.d.ts +9 -2
  19. package/esm/Avalanche/utils/txSizeLimits.js +1 -1
  20. package/esm/Avalanche/wallets/TxBuilderTypes.d.ts +110 -0
  21. package/esm/Avalanche/wallets/WalletAbstract.d.ts +17 -16
  22. package/esm/Avalanche/wallets/WalletAbstract.js +1 -1
  23. package/esm/BitcoinVM/providers/BitcoinProvider.d.ts +1 -0
  24. package/esm/BitcoinVM/providers/BitcoinProvider.js +1 -1
  25. package/esm/BitcoinVM/providers/BitcoinProviderAbstract.d.ts +1 -0
  26. package/esm/utils/assertFeeStateProvided.js +1 -0
  27. package/package.json +5 -5
@@ -0,0 +1,110 @@
1
+ import { utils, pvm, Common } from '@avalabs/avalanchejs';
2
+
3
+ type BaseTx = {
4
+ utxoSet: utils.UtxoSet;
5
+ chain: 'X' | 'P';
6
+ toAddress: string;
7
+ amountsPerAsset: Record<string, bigint>;
8
+ feeState?: pvm.FeeState;
9
+ options?: Common.SpendOptions;
10
+ fromAddresses?: string[];
11
+ };
12
+ type ImportP = {
13
+ utxoSet: utils.UtxoSet;
14
+ sourceChain: 'X' | 'C';
15
+ toAddress?: string;
16
+ threshold?: number;
17
+ feeState?: pvm.FeeState;
18
+ locktime?: bigint;
19
+ };
20
+ type ExportP = {
21
+ amount: bigint;
22
+ utxoSet: utils.UtxoSet;
23
+ destination: 'X' | 'C';
24
+ feeState?: pvm.FeeState;
25
+ toAddress?: string;
26
+ };
27
+ type ConsolidateP = {
28
+ utxoSet: utils.UtxoSet;
29
+ amount: bigint;
30
+ feeState?: pvm.FeeState;
31
+ toAddress?: string;
32
+ options?: Common.SpendOptions;
33
+ };
34
+ type CreateSubnet = {
35
+ utxoSet: utils.UtxoSet;
36
+ rewardAddresses: string[];
37
+ feeState?: pvm.FeeState;
38
+ fromAddresses?: string[];
39
+ options?: Common.SpendOptions;
40
+ threshold?: number;
41
+ locktime?: bigint;
42
+ };
43
+ type AddSubnetValidator = {
44
+ utxoSet: utils.UtxoSet;
45
+ nodeId: string;
46
+ start: bigint;
47
+ end: bigint;
48
+ weight: bigint;
49
+ subnetId: string;
50
+ subnetAuth: number[];
51
+ feeState?: pvm.FeeState;
52
+ fromAddresses?: string[];
53
+ options?: Common.SpendOptions;
54
+ };
55
+ type AddPermissionlessValidator = {
56
+ utxoSet: utils.UtxoSet;
57
+ nodeId: string;
58
+ start: bigint;
59
+ end: bigint;
60
+ weight: bigint;
61
+ subnetId: string;
62
+ shares: number;
63
+ fromAddresses?: string[];
64
+ rewardAddresses?: string[];
65
+ delegatorRewardAddresses?: string[];
66
+ publicKey?: Buffer;
67
+ signature?: Buffer;
68
+ options?: Common.SpendOptions;
69
+ stakingAssetId?: string;
70
+ locktime?: bigint;
71
+ threshold?: number;
72
+ feeState?: pvm.FeeState;
73
+ };
74
+ type AddPermissionlessDelegator = {
75
+ utxoSet: utils.UtxoSet;
76
+ nodeId: string;
77
+ start: bigint;
78
+ end: bigint;
79
+ weight: bigint;
80
+ subnetId: string;
81
+ fromAddresses?: string[];
82
+ rewardAddresses?: string[];
83
+ options?: Common.SpendOptions;
84
+ locktime?: bigint;
85
+ feeState?: pvm.FeeState;
86
+ stakingAssetId?: string;
87
+ threshold?: number;
88
+ };
89
+ type RemoveSubnetValidator = {
90
+ utxoSet: utils.UtxoSet;
91
+ nodeId: string;
92
+ subnetId: string;
93
+ subnetAuth: number[];
94
+ feeState?: pvm.FeeState;
95
+ fromAddresses?: string[];
96
+ options?: Common.SpendOptions;
97
+ };
98
+ type TransferSubnetOwnershipTx = {
99
+ utxoSet: utils.UtxoSet;
100
+ subnetId: string;
101
+ subnetAuth: number[];
102
+ subnetOwners: string[];
103
+ feeState?: pvm.FeeState;
104
+ fromAddresses?: string[];
105
+ options?: Common.SpendOptions;
106
+ threshold?: number;
107
+ locktime?: bigint;
108
+ };
109
+
110
+ export { AddPermissionlessDelegator, AddPermissionlessValidator, AddSubnetValidator, BaseTx, ConsolidateP, CreateSubnet, ExportP, ImportP, RemoveSubnetValidator, TransferSubnetOwnershipTx };
@@ -2,6 +2,7 @@ import * as _avalabs_avalanchejs from '@avalabs/avalanchejs';
2
2
  import { utils, pvm, Common } from '@avalabs/avalanchejs';
3
3
  import { AbstractProvider } from '../providers/AbstractProvider.js';
4
4
  import { ChainIDAlias } from '../models.js';
5
+ import { ImportP, ExportP, ConsolidateP, BaseTx, CreateSubnet, AddSubnetValidator, AddPermissionlessValidator, AddPermissionlessDelegator, RemoveSubnetValidator, TransferSubnetOwnershipTx } from './TxBuilderTypes.js';
5
6
 
6
7
  /**
7
8
  * An abstract class that that is shared by all wallet classes.
@@ -48,8 +49,12 @@ declare abstract class WalletAbstract {
48
49
  * @param source What is the source chain of the atomic UTXOs
49
50
  */
50
51
  getAtomicUTXOs(chain: ChainIDAlias, source: ChainIDAlias): Promise<utils.UtxoSet>;
52
+ /**
53
+ * Get the nonce of this wallet's C chain address
54
+ */
55
+ getNonce(): Promise<number>;
51
56
  exportX(amount: bigint, utxoSet: utils.UtxoSet, destination: 'P' | 'C', toAddress?: string): Common.UnsignedTx;
52
- importP(utxos: utils.UtxoSet, sourceChain: 'X' | 'C', toAddress?: string): Common.UnsignedTx;
57
+ importP({ utxoSet, sourceChain, toAddress, threshold, feeState, locktime, }: ImportP): Common.UnsignedTx;
53
58
  importX(utxos: utils.UtxoSet, sourceChain: 'P' | 'C', toAddress?: string): Common.UnsignedTx;
54
59
  /**
55
60
  *
@@ -69,10 +74,6 @@ declare abstract class WalletAbstract {
69
74
  * @param toAddress
70
75
  */
71
76
  exportC(amount: bigint, destination: 'X' | 'P', nonce: bigint, baseFee: bigint, toAddress?: string): _avalabs_avalanchejs.EVMUnsignedTx;
72
- /**
73
- * Get the nonce of this wallet's C chain address
74
- */
75
- getNonce(): Promise<number>;
76
77
  /**
77
78
  * Export the given amount of AVAX from the P chain. Export fee is automatically added.
78
79
  * @param amount
@@ -80,18 +81,18 @@ declare abstract class WalletAbstract {
80
81
  * @param destination
81
82
  * @param toAddress
82
83
  */
83
- exportP(amount: bigint, utxoSet: utils.UtxoSet, destination: 'X' | 'C', toAddress?: string): Common.UnsignedTx;
84
- addValidator(utxos: utils.UtxoSet, nodeID: string, stakeAmount: bigint, startDate: bigint, endDate: bigint, delegationFee: number, config?: {
84
+ exportP({ amount, utxoSet, destination, feeState, toAddress }: ExportP): Common.UnsignedTx;
85
+ addValidator(utxos: utils.UtxoSet, nodeId: string, stakeAmount: bigint, startDate: bigint, endDate: bigint, delegationFee: number, config?: {
85
86
  rewardAddress?: string;
86
87
  }): Common.UnsignedTx;
87
- addDelegator(utxos: utils.UtxoSet, nodeID: string, stakeAmount: bigint, startDate: bigint, endDate: bigint, config?: {
88
+ addDelegator(utxos: utils.UtxoSet, nodeId: string, stakeAmount: bigint, startDate: bigint, endDate: bigint, config?: {
88
89
  rewardAddress?: string;
89
90
  }): Common.UnsignedTx;
90
- consolidateP(utxoSet: utils.UtxoSet, amount: bigint, toAddress?: string, options?: Common.SpendOptions): Common.UnsignedTx;
91
- baseTX(utxoSet: utils.UtxoSet, chain: 'X' | 'P', toAddress: string, amountsPerAsset: Record<string, bigint>, options?: Common.SpendOptions, fromAddresses?: string[]): Common.UnsignedTx;
91
+ consolidateP({ utxoSet, amount, feeState, toAddress, options, }: ConsolidateP): Common.UnsignedTx;
92
+ baseTX({ utxoSet, chain, toAddress, amountsPerAsset, feeState, options, fromAddresses, }: BaseTx): Common.UnsignedTx;
92
93
  createBlockchain(utxoSet: utils.UtxoSet, subnetId: string, chainName: string, vmID: string, fxIds: string[], genesisData: Record<string, unknown>, subnetAuth: number[], options?: Common.SpendOptions, fromAddresses?: string[]): Common.UnsignedTx;
93
- createSubnet(utxoSet: utils.UtxoSet, rewardAddresses: string[], fromAddresses?: string[], options?: Common.SpendOptions, threshold?: number, locktime?: bigint): Common.UnsignedTx;
94
- addSubnetValidator(utxoSet: utils.UtxoSet, nodeId: string, start: bigint, end: bigint, weight: bigint, subnetId: string, subnetAuth: number[], fromAddresses?: string[], options?: Common.SpendOptions): Common.UnsignedTx;
94
+ createSubnet({ utxoSet, rewardAddresses, feeState, fromAddresses, options, threshold, locktime, }: CreateSubnet): Common.UnsignedTx;
95
+ addSubnetValidator({ utxoSet, nodeId, start, end, weight, subnetId, subnetAuth, feeState, fromAddresses, options, }: AddSubnetValidator): Common.UnsignedTx;
95
96
  /**
96
97
  *
97
98
  * @param utxoSet The transaction will be constructed from these UTXOs.
@@ -108,7 +109,7 @@ declare abstract class WalletAbstract {
108
109
  * @param signature the BLS signature, If the subnet is the primary network. Can be found in the Node on startup.
109
110
  * @param options
110
111
  */
111
- addPermissionlessValidator(utxoSet: utils.UtxoSet, nodeId: string, start: bigint, end: bigint, weight: bigint, subnetId: string, shares: number, fromAddresses?: string[], rewardAddresses?: string[], delegatorRewardAddresses?: string[], publicKey?: Buffer, signature?: Buffer, options?: Common.SpendOptions): Common.UnsignedTx;
112
+ addPermissionlessValidator({ utxoSet, nodeId, start, end, weight, subnetId, shares, feeState, fromAddresses, rewardAddresses, delegatorRewardAddresses, publicKey, signature, options, threshold, locktime, stakingAssetId, }: AddPermissionlessValidator): Common.UnsignedTx;
112
113
  /**
113
114
  *
114
115
  * @param utxoSet The transaction will be constructed from these UTXOs.
@@ -121,9 +122,9 @@ declare abstract class WalletAbstract {
121
122
  * @param rewardAddresses Will use active address if not provided. Given addresses will share the reward UTXO.
122
123
  * @param options
123
124
  */
124
- addPermissionlessDelegator(utxoSet: utils.UtxoSet, nodeId: string, start: bigint, end: bigint, weight: bigint, subnetId: string, fromAddresses?: string[], rewardAddresses?: string[], options?: Common.SpendOptions): Common.UnsignedTx;
125
- removeSubnetValidator(utxoSet: utils.UtxoSet, nodeId: string, subnetId: string, subnetAuth: number[], fromAddresses?: string[], options?: Common.SpendOptions): Common.UnsignedTx;
126
- transferSubnetOwnershipTx(utxoSet: utils.UtxoSet, subnetId: string, subnetAuth: number[], subnetOwners: string[], fromAddresses?: string[], options?: Common.SpendOptions, threshold?: number, locktime?: bigint): Common.UnsignedTx;
125
+ addPermissionlessDelegator({ utxoSet, nodeId, start, end, weight, subnetId, fromAddresses, rewardAddresses, options, locktime, feeState, threshold, stakingAssetId, }: AddPermissionlessDelegator): Common.UnsignedTx;
126
+ removeSubnetValidator({ utxoSet, nodeId, subnetId, subnetAuth, fromAddresses, feeState, options, }: RemoveSubnetValidator): Common.UnsignedTx;
127
+ transferSubnetOwnershipTx({ utxoSet, subnetId, subnetAuth, subnetOwners, feeState, fromAddresses, options, threshold, locktime, }: TransferSubnetOwnershipTx): Common.UnsignedTx;
127
128
  transformSubnetTx(utxoSet: utils.UtxoSet, subnetId: string, assetId: string, initialSupply: bigint, maximumSupply: bigint, minConsumptionRate: bigint, maxConsumptionRate: bigint, minValidatorStake: bigint, maxValidatorStake: bigint, minStakeDuration: number, maxStakeDuration: number, minDelegationFee: number, minDelegatorStake: number, maxValidatorWeightFactor: number, uptimeRequirement: number, subnetAuth: number[], fromAddresses?: string[], options?: Common.SpendOptions): Common.UnsignedTx;
128
129
  protected constructor(provider: AbstractProvider);
129
130
  }
@@ -1 +1 @@
1
- import{TransferableOutput as e,avm as t,pvm as s,evm as r,networkIDs as i,utils as d}from"@avalabs/avalanchejs";import"../utils/populateCredential.js";import{strip0x as o}from"@avalabs/core-utils-sdk";import"ethers";import"../providers/constants.js";import"@avalabs/core-chains-sdk";import"create-hash";import"bip32";import{getUTXOsForAddresses as n}from"../utils/getAllUTXOs.js";import{getStakeForAddresses as a}from"../utils/getStakeForAddresses.js";import"@avalabs/glacier-sdk";import"bip39";import"xss";import{sortUTXOsByAmount as g,sortUTXOsStaking as h,sortUTXOsByAmountAscending as p}from"../utils/sortUTXOs.js";import"bip32-path";const{parse:c,hexToBuffer:m}=d;class A{constructor(e){this.provider=e}setProvider(e){this.provider=e}getProvider(){return this.provider}async getUTXOs(e){const t=this.provider.getApi(e);return n(this.getAddresses(e),t)}async getStake(){const e=this.provider.getApiP();return a(this.getAddresses("P"),e)}async getAtomicUTXOs(e,t){if(e===t)throw new Error("Chain can not be the same as source chain.");const s=this.provider.getApi(e),r=this.provider.getChainID(t);return n(this.getAddresses(e),s,{sourceChain:r,addresses:[]})}exportX(s,r,i,d){d=d||this.getCurrentAddress(i);const o=c(d)[2],n=this.provider.getAvaxID(),a=e.fromNative(n,s,[o]),h=g(r.getUTXOs(),!0),p=this.provider.getChainID(i),m=this.getAddresses("X").map((e=>c(e)[2])),A=c(this.getChangeAddress("X"))[2];return t.newExportTx(this.provider.getContext(),p,m,h,[a],{threshold:1,changeAddresses:[A]})}importP(e,t,r){const i=this.provider.getChainID(t),d=this.getAddresses("P").map((e=>c(e)[2])),o=c(this.getChangeAddress("P"))[2];r=r||this.getCurrentAddress("P");const n=c(r)[2];return s.newImportTx(this.provider.getContext(),i,e.getUTXOs(),[n],d,{changeAddresses:[o]})}importX(e,s,r){const i=this.provider.getChainID(s),d=this.getAddresses("X").map((e=>c(e)[2])),o=c(this.getChangeAddress("X"))[2];r=r||this.getCurrentAddress("X");const n=c(r)[2];return t.newImportTx(this.provider.getContext(),i,e.getUTXOs(),[n],d,{changeAddresses:[o]})}importC(e,t,s,i,d){const n=this.provider.getChainID(t),a=this.getAddresses("C").map((e=>c(e)[2]));d=d||this.getAddressEVM();const g=Buffer.from(o(d),"hex");return r.newImportTxFromBaseFee(this.provider.getContext(),g,a,e.getUTXOs(),n,s,i)}exportC(e,t,s,i,d){const o=m(this.getAddressEVM()),n=this.provider.getChainID(t);d=d||this.getCurrentAddress(t);const a=c(d)[2],g=i/BigInt(1e9);return r.newExportTxFromBaseFee(this.provider.getContext(),g,e,n,o,[a],s)}async getNonce(){const e=this.getAddressEVM();return await this.provider.evmRpc.getTransactionCount(e)}exportP(t,r,i,d){d=d||this.getCurrentAddress(i);const o=c(d)[2],n=this.provider.getAvaxID(),a=e.fromNative(n,t,[o]),h=g(r.getUTXOs(),!0),p=this.provider.getChainID(i),m=this.getAddresses("P").map((e=>c(e)[2])),A=c(this.getChangeAddress("P"))[2];return s.newExportTx(this.provider.getContext(),p,m,h,[a],{changeAddresses:[A]})}addValidator(e,t,r,i,d,o,n){const a=h(e.getUTXOs()),g=this.getAddresses("P").map((e=>c(e)[2])),p=n?.rewardAddress||this.getCurrentAddress("P"),m=c(p)[2],A=c(this.getChangeAddress("P"))[2];return s.newAddValidatorTx(this.provider.getContext(),a,g,t,i,d,r,[m],o,{changeAddresses:[A]})}addDelegator(e,t,r,i,d,o){const n=h(e.getUTXOs()),a=this.getAddresses("P").map((e=>c(e)[2])),g=o?.rewardAddress||this.getCurrentAddress("P"),p=c(g)[2],m=c(this.getChangeAddress("P"))[2];return s.newAddDelegatorTx(this.provider.getContext(),n,a,t,i,d,r,[p],{changeAddresses:[m]})}consolidateP(t,r,i,d){const o=p(t.getUTXOs());i=i??this.getCurrentAddress("P");const n=c(i)[2],a=this.provider.getContext(),g=[e.fromNative(a.avaxAssetID,r,[n])],h=this.getAddresses("P").map((e=>c(e)[2]));return s.newBaseTx(this.provider.getContext(),h,o,g,d)}baseTX(r,i,d,o,n,a){const[h,p,m]=c(d);if(h!==i||p!==this.provider.getHrp())throw new Error(`Invalid recipient address "${d}"`);const A=Object.entries(o).map((([t,s])=>e.fromNative(t,s,[m]))),v=g(r.getUTXOs(),!0),u=(a??this.getAddresses(i)).map((e=>c(e)[2]));return"X"===i?t.newBaseTx(this.provider.getContext(),u,v,A,n):s.newBaseTx(this.provider.getContext(),u,v,A,n)}createBlockchain(e,t,r,i,d,o,n,a,h){const p=g(e.getUTXOs(),!0),m=(h??this.getAddresses("P")).map((e=>c(e)[2]));return s.newCreateBlockchainTx(this.provider.getContext(),p,m,t,r,i,d,o,n,a)}createSubnet(e,t,r,i,d,o){const n=g(e.getUTXOs(),!0),a=(r??this.getAddresses("P")).map((e=>c(e)[2])),h=t.map((e=>c(e)[2]));return s.newCreateSubnetTx(this.provider.getContext(),n,a,h,i,d??1,o??BigInt(0))}addSubnetValidator(e,t,r,i,d,o,n,a,h){const p=g(e.getUTXOs(),!0),m=(a??this.getAddresses("P")).map((e=>c(e)[2]));return s.newAddSubnetValidatorTx(this.provider.getContext(),p,m,t,r,i,d,o,n,h)}addPermissionlessValidator(e,t,r,d,o,n,a,g,p,m,A,v,u){const C=h(e.getUTXOs()),x=(g??this.getAddresses("P")).map((e=>c(e)[2])),T=(p??[this.getCurrentAddress("P")]).map((e=>c(e)[2])),l=(m??[this.getCurrentAddress("P")]).map((e=>c(e)[2]));if(!(n!==i.PrimaryNetworkID.toString()||A&&v))throw new Error("Must provide public key and signature for primary subnet.");const P={changeAddresses:[c(this.getChangeAddress("P"))[2]],...u??{}};return s.newAddPermissionlessValidatorTx(this.provider.getContext(),C,x,t,n,r,d,o,T,l,a,P,void 0,void 0,A,v)}addPermissionlessDelegator(e,t,r,i,d,o,n,a,g){const p=h(e.getUTXOs()),m=(n??this.getAddresses("P")).map((e=>c(e)[2])),A=(a??[this.getCurrentAddress("P")]).map((e=>c(e)[2])),v={changeAddresses:[c(this.getChangeAddress("P"))[2]],...g??{}};return s.newAddPermissionlessDelegatorTx(this.provider.getContext(),p,m,t,o,r,i,d,A,v,void 0,void 0)}removeSubnetValidator(e,t,r,i,d,o){const n=g(e.getUTXOs(),!0),a=(d??this.getAddresses("P")).map((e=>c(e)[2]));return s.newRemoveSubnetValidatorTx(this.provider.getContext(),n,a,t,r,i,o)}transferSubnetOwnershipTx(e,t,r,i,d,o,n,a){const h=g(e.getUTXOs(),!0),p=(d??this.getAddresses("P")).map((e=>c(e)[2])),m=i.map((e=>c(e)[2]));return s.newTransferSubnetOwnershipTx(this.provider.getContext(),h,p,t,r,m,o,n??1,a??BigInt(0))}transformSubnetTx(e,t,r,i,d,o,n,a,h,p,m,A,v,u,C,x,T,l){const P=g(e.getUTXOs(),!0),w=(T??this.getAddresses("P")).map((e=>c(e)[2]));return s.newTransformSubnetTx(this.provider.getContext(),P,w,t,r,i,d,o,n,a,h,p,m,A,v,u,C,x,l)}}export{A as WalletAbstract};
1
+ import{TransferableOutput as e,avm as t,pvm as s,evm as r,networkIDs as d,utils as i}from"@avalabs/avalanchejs";import"../utils/populateCredential.js";import{strip0x as o}from"@avalabs/core-utils-sdk";import"ethers";import"../providers/constants.js";import"@avalabs/core-chains-sdk";import"create-hash";import"bip32";import{getUTXOsForAddresses as n}from"../utils/getAllUTXOs.js";import{getStakeForAddresses as a}from"../utils/getStakeForAddresses.js";import"@avalabs/glacier-sdk";import"bip39";import"xss";import{sortUTXOsByAmount as h,sortUTXOsStaking as m,sortUTXOsByAmountAscending as g}from"../utils/sortUTXOs.js";import"bip32-path";import{assertFeeStateProvided as p}from"../../utils/assertFeeStateProvided.js";const{parse:u,hexToBuffer:A}=i,c=new Error("Tx type is not supported post-etna");class x{constructor(e){this.provider=e}setProvider(e){this.provider=e}getProvider(){return this.provider}async getUTXOs(e){const t=this.provider.getApi(e);return n(this.getAddresses(e),t)}async getStake(){const e=this.provider.getApiP();return a(this.getAddresses("P"),e)}async getAtomicUTXOs(e,t){if(e===t)throw new Error("Chain can not be the same as source chain.");const s=this.provider.getApi(e),r=this.provider.getChainID(t);return n(this.getAddresses(e),s,{sourceChain:r,addresses:[]})}async getNonce(){const e=this.getAddressEVM();return await this.provider.evmRpc.getTransactionCount(e)}exportX(s,r,d,i){i=i||this.getCurrentAddress(d);const o=u(i)[2],n=this.provider.getAvaxID(),a=e.fromNative(n,s,[o]),m=h(r.getUTXOs(),!0),g=this.provider.getChainID(d),p=this.getAddresses("X").map((e=>u(e)[2])),A=u(this.getChangeAddress("X"))[2];return t.newExportTx(this.provider.getContext(),g,p,m,[a],{threshold:1,changeAddresses:[A]})}importP({utxoSet:e,sourceChain:t,toAddress:r,threshold:d,feeState:i,locktime:o}){const n=this.provider.getChainID(t),a=this.getAddresses("P").map((e=>u(e)[2])),h=u(this.getChangeAddress("P"))[2];r=r||this.getCurrentAddress("P");const m=u(r)[2],g=e.getUTXOs();if(this.provider.isEtnaEnabled()){if(!i)throw new Error("feeState parameter is required post E-upgrade");return s.e.newImportTx({fromAddressesBytes:a,utxos:g,toAddressesBytes:[m],sourceChainId:n,threshold:d,feeState:i,locktime:o},this.provider.getContext())}return s.newImportTx(this.provider.getContext(),n,g,[m],a,{changeAddresses:[h]})}importX(e,s,r){const d=this.provider.getChainID(s),i=this.getAddresses("X").map((e=>u(e)[2])),o=u(this.getChangeAddress("X"))[2];r=r||this.getCurrentAddress("X");const n=u(r)[2];return t.newImportTx(this.provider.getContext(),d,e.getUTXOs(),[n],i,{changeAddresses:[o]})}importC(e,t,s,d,i){const n=this.provider.getChainID(t),a=this.getAddresses("C").map((e=>u(e)[2]));i=i||this.getAddressEVM();const h=Buffer.from(o(i),"hex");return r.newImportTxFromBaseFee(this.provider.getContext(),h,a,e.getUTXOs(),n,s,d)}exportC(e,t,s,d,i){const o=A(this.getAddressEVM()),n=this.provider.getChainID(t);i=i||this.getCurrentAddress(t);const a=u(i)[2],h=d/BigInt(1e9);return r.newExportTxFromBaseFee(this.provider.getContext(),h,e,n,o,[a],s)}exportP({amount:t,utxoSet:r,destination:d,feeState:i,toAddress:o}){o=o||this.getCurrentAddress(d);const n=u(o)[2],a=this.provider.getAvaxID(),m=e.fromNative(a,t,[n]),g=h(r.getUTXOs(),!0),A=this.provider.getChainID(d),c=this.getAddresses("P").map((e=>u(e)[2])),x=u(this.getChangeAddress("P"))[2];return this.provider.isEtnaEnabled()?(p(i),s.e.newExportTx({fromAddressesBytes:c,utxos:g,outputs:[m],destinationChainId:A,feeState:i},this.provider.getContext())):s.newExportTx(this.provider.getContext(),A,c,g,[m],{changeAddresses:[x]})}addValidator(e,t,r,d,i,o,n){const a=m(e.getUTXOs()),h=this.getAddresses("P").map((e=>u(e)[2])),g=n?.rewardAddress||this.getCurrentAddress("P"),p=u(g)[2],A=u(this.getChangeAddress("P"))[2];if(this.provider.isEtnaEnabled())throw c;return s.newAddValidatorTx(this.provider.getContext(),a,h,t,d,i,r,[p],o,{changeAddresses:[A]})}addDelegator(e,t,r,d,i,o){const n=m(e.getUTXOs()),a=this.getAddresses("P").map((e=>u(e)[2])),h=o?.rewardAddress||this.getCurrentAddress("P"),g=u(h)[2],p=u(this.getChangeAddress("P"))[2];if(this.provider.isEtnaEnabled())throw c;return s.newAddDelegatorTx(this.provider.getContext(),n,a,t,d,i,r,[g],{changeAddresses:[p]})}consolidateP({utxoSet:t,amount:r,feeState:d,toAddress:i,options:o}){const n=g(t.getUTXOs());i=i??this.getCurrentAddress("P");const a=u(i)[2],h=this.provider.getContext(),m=[e.fromNative(h.avaxAssetID,r,[a])],A=this.getAddresses("P").map((e=>u(e)[2]));return this.provider.isEtnaEnabled()?(p(d),s.e.newBaseTx({fromAddressesBytes:A,utxos:n,outputs:m,minIssuanceTime:o?.minIssuanceTime,memo:o?.memo,feeState:d},h)):s.newBaseTx(this.provider.getContext(),A,n,m,o)}baseTX({utxoSet:r,chain:d,toAddress:i,amountsPerAsset:o,feeState:n,options:a,fromAddresses:m}){const[g,A,c]=u(i);if(g!==d||A!==this.provider.getHrp())throw new Error(`Invalid recipient address "${i}"`);const x=Object.entries(o).map((([t,s])=>e.fromNative(t,s,[c]))),v=h(r.getUTXOs(),!0),l=(m??this.getAddresses(d)).map((e=>u(e)[2]));return"X"===d?t.newBaseTx(this.provider.getContext(),l,v,x,a):this.provider.isEtnaEnabled()?(p(n),s.e.newBaseTx({fromAddressesBytes:l,utxos:v,outputs:x,minIssuanceTime:a?.minIssuanceTime,memo:a?.memo,feeState:n},this.provider.getContext())):s.newBaseTx(this.provider.getContext(),l,v,x,a)}createBlockchain(e,t,r,d,i,o,n,a,m){const g=h(e.getUTXOs(),!0),p=(m??this.getAddresses("P")).map((e=>u(e)[2]));if(this.provider.isEtnaEnabled())throw c;return s.newCreateBlockchainTx(this.provider.getContext(),g,p,t,r,d,i,o,n,a)}createSubnet({utxoSet:e,rewardAddresses:t,feeState:r,fromAddresses:d,options:i,threshold:o,locktime:n}){const a=h(e.getUTXOs(),!0),m=(d??this.getAddresses("P")).map((e=>u(e)[2])),g=t.map((e=>u(e)[2]));return this.provider.isEtnaEnabled()?(p(r),s.e.newCreateSubnetTx({fromAddressesBytes:m,utxos:a,minIssuanceTime:i?.minIssuanceTime,memo:i?.memo,feeState:r,threshold:o,locktime:n,subnetOwners:g},this.provider.getContext())):s.newCreateSubnetTx(this.provider.getContext(),a,m,g,i,o??1,n??BigInt(0))}addSubnetValidator({utxoSet:e,nodeId:t,start:r,end:d,weight:i,subnetId:o,subnetAuth:n,feeState:a,fromAddresses:m,options:g}){const A=h(e.getUTXOs(),!0),c=(m??this.getAddresses("P")).map((e=>u(e)[2]));return this.provider.isEtnaEnabled()?(p(a),s.e.newAddSubnetValidatorTx({fromAddressesBytes:c,utxos:A,minIssuanceTime:g?.minIssuanceTime,memo:g?.memo,nodeId:t,start:r,end:d,weight:i,subnetId:o,subnetAuth:n,feeState:a},this.provider.getContext())):s.newAddSubnetValidatorTx(this.provider.getContext(),A,c,t,r,d,i,o,n,g)}addPermissionlessValidator({utxoSet:e,nodeId:t,start:r,end:i,weight:o,subnetId:n,shares:a,feeState:h,fromAddresses:g,rewardAddresses:A,delegatorRewardAddresses:c,publicKey:x,signature:v,options:l,threshold:T,locktime:f,stakingAssetId:C}){const w=m(e.getUTXOs()),b=(g??this.getAddresses("P")).map((e=>u(e)[2])),I=(A??[this.getCurrentAddress("P")]).map((e=>u(e)[2])),S=(c??[this.getCurrentAddress("P")]).map((e=>u(e)[2]));if(!(n!==d.PrimaryNetworkID.toString()||x&&v))throw new Error("Must provide public key and signature for primary subnet.");const P=u(this.getChangeAddress("P"))[2];if(this.provider.isEtnaEnabled())return p(h),s.e.newAddPermissionlessValidatorTx({fromAddressesBytes:b,delegatorRewardsOwner:S,utxos:w,minIssuanceTime:l?.minIssuanceTime,memo:l?.memo,changeAddressesBytes:l?.changeAddresses?l.changeAddresses:[P],nodeId:t,start:r,end:i,weight:o,subnetId:n,shares:a,feeState:h,publicKey:x,rewardAddresses:I,signature:v,locktime:f,threshold:T,stakingAssetId:C},this.provider.getContext());const E={changeAddresses:[P],...l??{}};return s.newAddPermissionlessValidatorTx(this.provider.getContext(),w,b,t,n,r,i,o,I,S,a,E,void 0,void 0,x,v)}addPermissionlessDelegator({utxoSet:e,nodeId:t,start:r,end:d,weight:i,subnetId:o,fromAddresses:n,rewardAddresses:a,options:h,locktime:g,feeState:A,threshold:c,stakingAssetId:x}){const v=m(e.getUTXOs()),l=(n??this.getAddresses("P")).map((e=>u(e)[2])),T=(a??[this.getCurrentAddress("P")]).map((e=>u(e)[2])),f=u(this.getChangeAddress("P"))[2];if(this.provider.isEtnaEnabled())return p(A),s.e.newAddPermissionlessDelegatorTx({fromAddressesBytes:l,utxos:v,minIssuanceTime:h?.minIssuanceTime,memo:h?.memo,changeAddressesBytes:h?.changeAddresses?h.changeAddresses:[f],nodeId:t,start:r,end:d,weight:i,subnetId:o,rewardAddresses:T,locktime:g,stakingAssetId:x,threshold:c,feeState:A},this.provider.getContext());const C={changeAddresses:[f],...h??{}};return s.newAddPermissionlessDelegatorTx(this.provider.getContext(),v,l,t,o,r,d,i,T,C,void 0,void 0)}removeSubnetValidator({utxoSet:e,nodeId:t,subnetId:r,subnetAuth:d,fromAddresses:i,feeState:o,options:n}){const a=h(e.getUTXOs(),!0),m=(i??this.getAddresses("P")).map((e=>u(e)[2]));return this.provider.isEtnaEnabled()?(p(o),s.e.newRemoveSubnetValidatorTx({fromAddressesBytes:m,utxos:a,minIssuanceTime:n?.minIssuanceTime,memo:n?.memo,nodeId:t,subnetId:r,subnetAuth:d,feeState:o},this.provider.getContext())):s.newRemoveSubnetValidatorTx(this.provider.getContext(),a,m,t,r,d,n)}transferSubnetOwnershipTx({utxoSet:e,subnetId:t,subnetAuth:r,subnetOwners:d,feeState:i,fromAddresses:o,options:n,threshold:a,locktime:m}){const g=h(e.getUTXOs(),!0),A=(o??this.getAddresses("P")).map((e=>u(e)[2])),c=d.map((e=>u(e)[2]));return this.provider.isEtnaEnabled()?(p(i),s.e.newTransferSubnetOwnershipTx({fromAddressesBytes:A,utxos:g,minIssuanceTime:n?.minIssuanceTime,memo:n?.memo,subnetId:t,subnetAuth:r,subnetOwners:c,feeState:i,threshold:a,locktime:m},this.provider.getContext())):s.newTransferSubnetOwnershipTx(this.provider.getContext(),g,A,t,r,c,n,a??1,m??BigInt(0))}transformSubnetTx(e,t,r,d,i,o,n,a,m,g,p,A,x,v,l,T,f,C){const w=h(e.getUTXOs(),!0),b=(f??this.getAddresses("P")).map((e=>u(e)[2]));if(this.provider.isEtnaEnabled())throw c;return s.newTransformSubnetTx(this.provider.getContext(),w,b,t,r,d,i,o,n,a,m,g,p,A,x,v,l,T,C)}}export{x as WalletAbstract};
@@ -12,6 +12,7 @@ declare class BitcoinProvider extends BitcoinProviderAbstract {
12
12
  confirmed: BitcoinInputUTXOWithOptionalScript[];
13
13
  unconfirmed: BitcoinInputUTXOWithOptionalScript[];
14
14
  }>;
15
+ getAddressFromScript(script: string): Promise<string>;
15
16
  getScriptsForUtxos(utxos: BitcoinInputUTXOWithOptionalScript[]): Promise<BitcoinInputUTXO[]>;
16
17
  private _parseUtxo;
17
18
  getBalances(address: string): Promise<{
@@ -1 +1 @@
1
- import{BitcoinProviderAbstract as t}from"./BitcoinProviderAbstract.js";import{networks as e}from"bitcoinjs-lib";import{HttpClient as a}from"@avalabs/core-utils-sdk";import{URL_EXPLORER_MAINNET as s,URL_EXPLORER_TESTNET as r,URL_NODE_MAINNET as i,URL_NODE_TESTNET as n}from"./models.js";import{parseAddressFullTx as o}from"./utils/parseAddressFullTx.js";class l extends t{constructor(t=!0,e,o,l,m){super(),this.isMainnet=t,this.extraParams=m;const c=e?{headers:{"api-key":e}}:{},p=t?s:r;this.#t=new a(o||p,c);const u=t?i:n;this.#e=new a(l||u,c)}#t;#e;async#a(t){return this.isMainnet?(await Promise.all(t.map((t=>this.#e.post("",t,{},this.extraParams))))).flat():this.#e.post("",t,{},this.extraParams)}async getTxHex(t){return(await this.#t.post(`/api/v2/tx/${t}`,{},{},this.extraParams)).hex}async getUTXOs(t,e=!0){const a=await this.#t.post(`/api/v2/utxo/${t}`,{},{},this.extraParams);if(!a?.length)return{confirmed:[],unconfirmed:[]};const s=a.map(this._parseUtxo),r=t=>({confirmed:t.filter((t=>t.confirmations>0)),unconfirmed:t.filter((t=>0===t.confirmations))});if(!e)return r(s);return r(await this.getScriptsForUtxos(s))}async getScriptsForUtxos(t){const[e,a]=t.reduce((([t,e],a)=>a.script?[[...t,a],e]:[t,[...e,a]]),[[],[]]),s=a.map(((t,e)=>({jsonrpc:"2.0",method:"gettxout",params:[t.txHash,t.index],id:`${e}`}))),r=s.length?(await this.#a(s)).sort(((t,e)=>Number(t.id)-Number(e.id))):[];return[...e,...a.map(((t,e)=>({...t,script:r[e]?.result?.scriptPubKey.hex})))]}_parseUtxo(t){return{...t,txHash:t.txid,index:t.vout,value:Number(t.value),blockHeight:t.height,script:t.script,confirmations:t.confirmations}}async getBalances(t){const e=await this.#t.post(`/api/v2/address/${t}`,{},{},this.extraParams);return{available:BigInt(e.balance),pending:BigInt(e.unconfirmedBalance),final:BigInt(e.balance)+BigInt(e.unconfirmedBalance)}}async getChainHeight(){return(await this.#e.post("",{jsonrpc:"2.0",id:"nownodes",method:"getblockcount",params:[]},{},this.extraParams)).result}async getFeeRates(){const t={jsonrpc:"2.0",method:"estimatesmartfee"},e=await this.#a([{...t,id:"1",params:[1]},{...t,id:"2",params:[3]},{...t,id:"3",params:[7]}]).then((t=>t.sort(((t,e)=>Number(t.id)-Number(e.id))).map((t=>1e8*(t.result?.feerate??0)))));return{high:Math.round(e[0]/1024)||1,medium:Math.round(e[1]/1024)||1,low:Math.floor(e[2]/1024)||1}}getNetwork(){return this.isMainnet?e.bitcoin:e.testnet}async issueRawTx(t){return await this.#e.post("",{jsonrpc:"2.0",id:"nownodes",method:"sendrawtransaction",params:[t]},{},this.extraParams).then((t=>t.result))}async getTransaction(t){const e=await this.#t.post(`/api/v2/tx/${t}`,{},{},this.extraParams);return{block:e.blockHeight,fees:Number(e.fees),confirmations:e.confirmations,amount:Number(e.value),hash:e.txid,addresses:Array.from(new Set([...e.vin.map((t=>t.addresses||[])).flat(),...e.vout.map((t=>t.addresses||[])).flat()])),blockTime:e.blockTime,inputs:[...e.vin.map((t=>({...t,value:Number(t.value)})))],outputs:[...e.vout.map((t=>({...t,value:Number(t.value)})))]}}async getTxHistory(t){const e=await this.#t.post(`/api/v2/address/${t}`,{},{},this.extraParams);return await Promise.allSettled(e.txids?.slice(0,25).map((async e=>{try{const a=await this.#t.post(`/api/v2/tx/${e}`,{},{},this.extraParams);return o(t,a)}catch(t){console.log(`Unable to parse full tx ${e}.`)}}))).then((t=>t.map((t=>"fulfilled"===t.status&&t.value?t.value:void 0)).filter((t=>void 0!==t))))}async waitForTx(t,{maxAttempts:e=20,attempt:a=1,pollInterval:s=500}={}){try{return await this.getTransaction(t)}catch(r){if(a>=e)throw r;return await new Promise((t=>setTimeout(t,s))),this.waitForTx(t,{maxAttempts:e,attempt:a+1,pollInterval:s})}}}export{l as BitcoinProvider};
1
+ import{BitcoinProviderAbstract as t}from"./BitcoinProviderAbstract.js";import{networks as e}from"bitcoinjs-lib";import{HttpClient as a}from"@avalabs/core-utils-sdk";import{URL_EXPLORER_MAINNET as s,URL_EXPLORER_TESTNET as r,URL_NODE_MAINNET as i,URL_NODE_TESTNET as n}from"./models.js";import{parseAddressFullTx as o}from"./utils/parseAddressFullTx.js";class l extends t{constructor(t=!0,e,o,l,c){super(),this.isMainnet=t,this.extraParams=c;const m=e?{headers:{"api-key":e}}:{},p=t?s:r;this.#t=new a(o||p,m);const d=t?i:n;this.#e=new a(l||d,m)}#t;#e;async#a(t){return this.isMainnet?(await Promise.all(t.map((t=>this.#e.post("",t,{},this.extraParams))))).flat():this.#e.post("",t,{},this.extraParams)}async getTxHex(t){return(await this.#t.post(`/api/v2/tx/${t}`,{},{},this.extraParams)).hex}async getUTXOs(t,e=!0){const a=await this.#t.post(`/api/v2/utxo/${t}`,{},{},this.extraParams);if(!a?.length)return{confirmed:[],unconfirmed:[]};const s=a.map(this._parseUtxo),r=t=>({confirmed:t.filter((t=>t.confirmations>0)),unconfirmed:t.filter((t=>0===t.confirmations))});if(!e)return r(s);return r(await this.getScriptsForUtxos(s))}async getAddressFromScript(t){const e=await this.#e.post("",{jsonrpc:"2.0",id:`decode-script-${t}`,method:"decodescript",params:[t]},{},this.extraParams);if(e.result)return e.result.address;throw new Error(`Unable to resolve address for script: ${t}. ${e.error.message}`)}async getScriptsForUtxos(t){const[e,a]=t.reduce((([t,e],a)=>a.script?[[...t,a],e]:[t,[...e,a]]),[[],[]]),s=a.map(((t,e)=>({jsonrpc:"2.0",method:"gettxout",params:[t.txHash,t.index],id:`${e}`}))),r=s.length?(await this.#a(s)).sort(((t,e)=>Number(t.id)-Number(e.id))):[];return[...e,...a.map(((t,e)=>({...t,script:r[e]?.result?.scriptPubKey.hex})))]}_parseUtxo(t){return{...t,txHash:t.txid,index:t.vout,value:Number(t.value),blockHeight:t.height,script:t.script,confirmations:t.confirmations}}async getBalances(t){const e=await this.#t.post(`/api/v2/address/${t}`,{},{},this.extraParams);return{available:BigInt(e.balance),pending:BigInt(e.unconfirmedBalance),final:BigInt(e.balance)+BigInt(e.unconfirmedBalance)}}async getChainHeight(){return(await this.#e.post("",{jsonrpc:"2.0",id:"nownodes",method:"getblockcount",params:[]},{},this.extraParams)).result}async getFeeRates(){const t={jsonrpc:"2.0",method:"estimatesmartfee"},e=await this.#a([{...t,id:"1",params:[1]},{...t,id:"2",params:[3]},{...t,id:"3",params:[6]}]).then((t=>t.sort(((t,e)=>Number(t.id)-Number(e.id))).map((t=>1e8*(t.result?.feerate??0)))));return{high:Math.ceil(e[0]/1024)||1,medium:Math.ceil(e[1]/1024)||1,low:Math.ceil(e[2]/1024)||1}}getNetwork(){return this.isMainnet?e.bitcoin:e.testnet}async issueRawTx(t){return await this.#e.post("",{jsonrpc:"2.0",id:"nownodes",method:"sendrawtransaction",params:[t]},{},this.extraParams).then((t=>t.result))}async getTransaction(t){const e=await this.#t.post(`/api/v2/tx/${t}`,{},{},this.extraParams);return{block:e.blockHeight,fees:Number(e.fees),confirmations:e.confirmations,amount:Number(e.value),hash:e.txid,addresses:Array.from(new Set([...e.vin.map((t=>t.addresses||[])).flat(),...e.vout.map((t=>t.addresses||[])).flat()])),blockTime:e.blockTime,inputs:[...e.vin.map((t=>({...t,value:Number(t.value)})))],outputs:[...e.vout.map((t=>({...t,value:Number(t.value)})))]}}async getTxHistory(t){const e=await this.#t.post(`/api/v2/address/${t}`,{},{},this.extraParams);return await Promise.allSettled(e.txids?.slice(0,25).map((async e=>{try{const a=await this.#t.post(`/api/v2/tx/${e}`,{},{},this.extraParams);return o(t,a)}catch(t){console.log(`Unable to parse full tx ${e}.`)}}))).then((t=>t.map((t=>"fulfilled"===t.status&&t.value?t.value:void 0)).filter((t=>void 0!==t))))}async waitForTx(t,{maxAttempts:e=20,attempt:a=1,pollInterval:s=500}={}){try{return await this.getTransaction(t)}catch(r){if(a>=e)throw r;return await new Promise((t=>setTimeout(t,s))),this.waitForTx(t,{maxAttempts:e,attempt:a+1,pollInterval:s})}}}export{l as BitcoinProvider};
@@ -58,6 +58,7 @@ declare abstract class BitcoinProviderAbstract {
58
58
  medium: number;
59
59
  low: number;
60
60
  }>;
61
+ abstract getAddressFromScript(script: string): Promise<string>;
61
62
  }
62
63
 
63
64
  export { BitcoinProviderAbstract };
@@ -0,0 +1 @@
1
+ function e(e){if("object"!=typeof e||!e)throw new Error("feeState parameter is required post E-upgrade")}export{e as assertFeeStateProvided};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@avalabs/core-wallets-sdk",
3
- "version": "3.1.0-alpha.1",
3
+ "version": "3.1.0-alpha.11",
4
4
  "license": "Limited Ecosystem License",
5
5
  "private": false,
6
6
  "main": "dist/index.js",
@@ -30,9 +30,9 @@
30
30
  "ts-jest": "29.1.2"
31
31
  },
32
32
  "dependencies": {
33
- "@avalabs/avalanchejs": "4.0.5",
34
- "@avalabs/core-chains-sdk": "3.1.0-alpha.1",
35
- "@avalabs/glacier-sdk": "3.1.0-alpha.1",
33
+ "@avalabs/avalanchejs": "4.1.0-alpha.15",
34
+ "@avalabs/core-chains-sdk": "3.1.0-alpha.11",
35
+ "@avalabs/glacier-sdk": "3.1.0-alpha.11",
36
36
  "@avalabs/hw-app-avalanche": "0.14.1",
37
37
  "@ledgerhq/hw-app-btc": "10.2.4",
38
38
  "@ledgerhq/hw-app-eth": "6.36.1",
@@ -52,5 +52,5 @@
52
52
  "peerDependencies": {
53
53
  "ethers": "^6.7.1"
54
54
  },
55
- "gitHead": "f1156dfcfb7e6968685a513a67d34740a5a8adce"
55
+ "gitHead": "e92a86e9a086b3e2a4fc014bf744755a7a58a1f9"
56
56
  }