@leofcoin/lib 1.3.8 → 1.3.9

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.
@@ -26,15 +26,30 @@ export declare const nameServiceMessage: string;
26
26
  export declare const validatorsMessage: string;
27
27
  export declare const TRANSACTION_FEE_BYTES = 1024n;
28
28
  export declare const TRANSACTION_FEE_UNIT = 10n;
29
- export declare const FEE_BURN_BASIS_POINTS = 1000n;
29
+ export declare const MAX_TRANSACTION_BYTES: number;
30
+ export declare const MAX_BLOCK_TRANSACTION_BYTES: number;
31
+ export declare const MAX_BLOCK_TRANSACTIONS = 256;
32
+ export declare const MAX_TRANSACTION_FEE: bigint;
30
33
  export declare const FEE_BASIS_POINTS = 10000n;
31
34
  export declare const FEE_PROTOCOL_VERSION = "1.10.9";
35
+ export declare const MONETARY_POLICY_PROTOCOL_VERSION = "1.10.10";
36
+ export declare const BLOCKS_PER_YEAR = 5256000n;
37
+ export declare const ANNUAL_ISSUANCE_BASIS_POINTS = 200n;
38
+ export declare const SUPPLY_FLOOR_BASIS_POINTS = 9500n;
39
+ export declare const MONETARY_FEE_BURN_BASIS_POINTS = 1000n;
32
40
  export declare const supportsTransactionFees: (version: string) => boolean;
41
+ export declare const supportsMonetaryPolicy: (version: string) => boolean;
42
+ export declare const calculateMonetaryPolicy: (totalSupply: bigint, targetSupply: bigint) => {
43
+ subsidy: bigint;
44
+ burnBasisPoints: bigint;
45
+ floorSupply: bigint;
46
+ };
47
+ export declare const distributeAmount: (amount: bigint, addresses: string[], rotation?: number) => Map<string, bigint>;
33
48
  export type FeePayment = {
34
49
  to: string;
35
50
  amount: bigint;
36
51
  };
37
- export declare const distributeTransactionFee: (fee: bigint, transactionHash: string, validatorAddresses: string[]) => {
52
+ export declare const distributeTransactionFee: (fee: bigint, transactionHash: string, validatorAddresses: string[], burnBasisPoints?: bigint) => {
38
53
  burned: bigint;
39
54
  validatorFees: Map<string, bigint>;
40
55
  payments: FeePayment[];
@@ -42,9 +57,11 @@ export declare const distributeTransactionFee: (fee: bigint, transactionHash: st
42
57
  export declare const aggregateValidatorFees: (fees: Array<{
43
58
  fee: bigint;
44
59
  transactionHash: string;
45
- }>, validatorAddresses: string[]) => Map<string, bigint>;
60
+ }>, validatorAddresses: string[], burnBasisPoints?: bigint) => Map<string, bigint>;
46
61
  export declare const createContractMessage: (creator: any, contract: any, constructorParameters?: never[]) => Promise<ContractMessage>;
47
62
  export declare const calculateFee: (transaction: any, format?: boolean) => Promise<string | bigint>;
63
+ export declare const validateTransactionResourceLimits: (transaction: any) => Promise<number>;
64
+ export declare const validateBlockResourceLimits: (transactions: any) => Promise<number>;
48
65
  export declare const calculateTransactionFee: (transaction: any) => Promise<string | bigint>;
49
66
  export declare const calculateReward: (validators: any, fees: any) => [];
50
67
  export declare const createTransactionHash: (transaction: rawTransaction | TransactionMessage | RawTransactionMessage) => Promise<Uint8Array>;
package/exports/index.js CHANGED
@@ -21,9 +21,17 @@ const nameServiceMessage = bytecodes.nameService;
21
21
  const validatorsMessage = bytecodes.validators;
22
22
  const TRANSACTION_FEE_BYTES = 1024n;
23
23
  const TRANSACTION_FEE_UNIT = 10n;
24
- const FEE_BURN_BASIS_POINTS = 1000n;
24
+ const MAX_TRANSACTION_BYTES = 32 * 1024;
25
+ const MAX_BLOCK_TRANSACTION_BYTES = 128 * 1024;
26
+ const MAX_BLOCK_TRANSACTIONS = 256;
27
+ const MAX_TRANSACTION_FEE = (BigInt(MAX_TRANSACTION_BYTES) / TRANSACTION_FEE_BYTES) * TRANSACTION_FEE_UNIT;
25
28
  const FEE_BASIS_POINTS = 10000n;
26
29
  const FEE_PROTOCOL_VERSION = '1.10.9';
30
+ const MONETARY_POLICY_PROTOCOL_VERSION = '1.10.10';
31
+ const BLOCKS_PER_YEAR = 5256000n;
32
+ const ANNUAL_ISSUANCE_BASIS_POINTS = 200n;
33
+ const SUPPLY_FLOOR_BASIS_POINTS = 9500n;
34
+ const MONETARY_FEE_BURN_BASIS_POINTS = 1000n;
27
35
  const parseProtocolVersion = (version) => {
28
36
  const match = /^(\d+)\.(\d+)\.(\d+)/.exec(version);
29
37
  return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : undefined;
@@ -39,19 +47,61 @@ const supportsTransactionFees = (version) => {
39
47
  }
40
48
  return true;
41
49
  };
50
+ const supportsMonetaryPolicy = (version) => {
51
+ const actual = parseProtocolVersion(version);
52
+ const required = parseProtocolVersion(MONETARY_POLICY_PROTOCOL_VERSION);
53
+ if (!actual)
54
+ return false;
55
+ for (let index = 0; index < required.length; index += 1) {
56
+ if (actual[index] !== required[index])
57
+ return actual[index] > required[index];
58
+ }
59
+ return true;
60
+ };
61
+ const calculateMonetaryPolicy = (totalSupply, targetSupply) => {
62
+ if (totalSupply < 0n || targetSupply <= 0n)
63
+ throw new Error('invalid monetary policy supply');
64
+ const floorSupply = (targetSupply * SUPPLY_FLOOR_BASIS_POINTS) / FEE_BASIS_POINTS;
65
+ if (totalSupply < floorSupply) {
66
+ const annualIssuance = (targetSupply * ANNUAL_ISSUANCE_BASIS_POINTS) / FEE_BASIS_POINTS;
67
+ const scheduled = annualIssuance / BLOCKS_PER_YEAR || 1n;
68
+ return { subsidy: scheduled < floorSupply - totalSupply ? scheduled : floorSupply - totalSupply, burnBasisPoints: 0n, floorSupply };
69
+ }
70
+ return {
71
+ subsidy: 0n,
72
+ burnBasisPoints: totalSupply >= targetSupply ? MONETARY_FEE_BURN_BASIS_POINTS : 0n,
73
+ floorSupply
74
+ };
75
+ };
76
+ const distributeAmount = (amount, addresses, rotation = 0) => {
77
+ const canonical = [...new Set(addresses)].sort();
78
+ if (canonical.length === 0)
79
+ throw new Error('cannot distribute without validators');
80
+ const count = BigInt(canonical.length);
81
+ const base = amount / count;
82
+ const remainder = Number(amount % count);
83
+ const result = new Map(canonical.map((address) => [address, base]));
84
+ for (let index = 0; index < remainder; index += 1) {
85
+ const address = canonical[(rotation + index) % canonical.length];
86
+ result.set(address, result.get(address) + 1n);
87
+ }
88
+ return result;
89
+ };
42
90
  const feeRotationIndex = (transactionHash, validatorCount) => {
43
91
  let value = 0n;
44
92
  for (const character of transactionHash)
45
93
  value = (value * 31n + BigInt(character.charCodeAt(0))) % 4294967291n;
46
94
  return Number(value % BigInt(validatorCount));
47
95
  };
48
- const distributeTransactionFee = (fee, transactionHash, validatorAddresses) => {
96
+ const distributeTransactionFee = (fee, transactionHash, validatorAddresses, burnBasisPoints = 1000n) => {
49
97
  const canonicalValidators = [...new Set(validatorAddresses)].sort();
50
98
  if (canonicalValidators.length === 0)
51
99
  throw new Error('cannot distribute transaction fee without validators');
52
100
  if (fee < 0n)
53
101
  throw new Error('transaction fee cannot be negative');
54
- const burned = (fee * FEE_BURN_BASIS_POINTS) / FEE_BASIS_POINTS;
102
+ if (burnBasisPoints < 0n || burnBasisPoints > FEE_BASIS_POINTS)
103
+ throw new Error('invalid fee burn rate');
104
+ const burned = (fee * burnBasisPoints) / FEE_BASIS_POINTS;
55
105
  const validatorPool = fee - burned;
56
106
  const count = BigInt(canonicalValidators.length);
57
107
  const base = validatorPool / count;
@@ -67,10 +117,10 @@ const distributeTransactionFee = (fee, transactionHash, validatorAddresses) => {
67
117
  .map(([to, amount]) => ({ to, amount }));
68
118
  return { burned, validatorFees, payments };
69
119
  };
70
- const aggregateValidatorFees = (fees, validatorAddresses) => {
120
+ const aggregateValidatorFees = (fees, validatorAddresses, burnBasisPoints = 1000n) => {
71
121
  const totals = new Map([...new Set(validatorAddresses)].sort().map((validator) => [validator, 0n]));
72
122
  for (const entry of fees) {
73
- const { validatorFees } = distributeTransactionFee(entry.fee, entry.transactionHash, validatorAddresses);
123
+ const { validatorFees } = distributeTransactionFee(entry.fee, entry.transactionHash, validatorAddresses, burnBasisPoints);
74
124
  for (const [validator, amount] of validatorFees)
75
125
  totals.set(validator, totals.get(validator) + amount);
76
126
  }
@@ -90,6 +140,26 @@ const calculateFee = async (transaction, format = false) => {
90
140
  const fee = units * TRANSACTION_FEE_UNIT;
91
141
  return format ? formatUnits(fee.toString()) : fee;
92
142
  };
143
+ const validateTransactionResourceLimits = async (transaction) => {
144
+ const message = await new TransactionMessage(transaction);
145
+ const size = message.encoded.length;
146
+ if (size > MAX_TRANSACTION_BYTES) {
147
+ throw new Error(`transaction exceeds ${MAX_TRANSACTION_BYTES} byte protocol limit: ${size}`);
148
+ }
149
+ return size;
150
+ };
151
+ const validateBlockResourceLimits = async (transactions) => {
152
+ if (transactions.length > MAX_BLOCK_TRANSACTIONS) {
153
+ throw new Error(`block exceeds ${MAX_BLOCK_TRANSACTIONS} transaction protocol limit`);
154
+ }
155
+ let size = 0;
156
+ for (const transaction of transactions)
157
+ size += await validateTransactionResourceLimits(transaction);
158
+ if (size > MAX_BLOCK_TRANSACTION_BYTES) {
159
+ throw new Error(`block transactions exceed ${MAX_BLOCK_TRANSACTION_BYTES} byte protocol limit: ${size}`);
160
+ }
161
+ return size;
162
+ };
93
163
  const calculateTransactionFee = (transaction) => {
94
164
  transaction = new TransactionMessage(transaction);
95
165
  return calculateFee(transaction);
@@ -144,4 +214,4 @@ const prepareContractTransactionAndSign = async (owner, contract, constructorPar
144
214
  return signTransaction(transaction, wallet);
145
215
  };
146
216
 
147
- export { FEE_BASIS_POINTS, FEE_BURN_BASIS_POINTS, FEE_PROTOCOL_VERSION, TRANSACTION_FEE_BYTES, TRANSACTION_FEE_UNIT, aggregateValidatorFees, calculateFee, calculateReward, calculateTransactionFee, contractFactoryMessage, createContractMessage, createTransactionHash, distributeTransactionFee, nameServiceMessage, nativeTokenMessage, prepareContractTransaction, prepareContractTransactionAndSign, signTransaction, supportsTransactionFees, validatorsMessage };
217
+ export { ANNUAL_ISSUANCE_BASIS_POINTS, BLOCKS_PER_YEAR, FEE_BASIS_POINTS, FEE_PROTOCOL_VERSION, MAX_BLOCK_TRANSACTIONS, MAX_BLOCK_TRANSACTION_BYTES, MAX_TRANSACTION_BYTES, MAX_TRANSACTION_FEE, MONETARY_FEE_BURN_BASIS_POINTS, MONETARY_POLICY_PROTOCOL_VERSION, SUPPLY_FLOOR_BASIS_POINTS, TRANSACTION_FEE_BYTES, TRANSACTION_FEE_UNIT, aggregateValidatorFees, calculateFee, calculateMonetaryPolicy, calculateReward, calculateTransactionFee, contractFactoryMessage, createContractMessage, createTransactionHash, distributeAmount, distributeTransactionFee, nameServiceMessage, nativeTokenMessage, prepareContractTransaction, prepareContractTransactionAndSign, signTransaction, supportsMonetaryPolicy, supportsTransactionFees, validateBlockResourceLimits, validateTransactionResourceLimits, validatorsMessage };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leofcoin/lib",
3
- "version": "1.3.8",
3
+ "version": "1.3.9",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "typings": "./exports/typings/index.d.ts",