UNPKG

@planetarium/tx

Version:

Creating Libplanet transactions from JavaScript/TypeScript

8 lines (7 loc) 13.9 kB
{ "version": 3, "sources": ["../src/index.ts", "../src/binary.ts", "../src/address.ts", "../src/assets.ts", "../src/tx/metadata.ts", "../src/blockhash.ts", "../src/key.ts", "../src/tx/unsigned.ts", "../src/tx/signed.ts", "../src/bytes.ts"], "sourcesContent": ["export { type Address, encodeAddress } from \"./address.js\";\nexport {\n type Currency,\n encodeCurrency,\n type FungibleAssetValue,\n encodeFungibleAssetValue,\n getCurrencyHash,\n getMajorUnit,\n getMinorUnit,\n getSign,\n} from \"./assets.js\";\nexport type {\n TxMetadata,\n UnsignedTx,\n} from \"./tx/index.js\";\nexport {\n encodeTxMetadata,\n encodeUnsignedTx,\n} from \"./tx/index.js\";\nexport {\n signTx,\n encodeSignedTx,\n} from \"./tx/signed.js\";\n", "\nexport function compareUint8Array(a: Uint8Array, b: Uint8Array) {\n const length = Math.min(a.length, b.length);\n for (let i = 0; i < length; i++) {\n if (a[i] !== b[i]) return a[i] - b[i];\n }\n return a.length - b.length;\n}\n", "import { Key, Value } from \"@planetarium/bencodex\";\nimport { compareUint8Array } from \"./binary.js\";\n\nexport type Address = Uint8Array; // TODO: proper type definition\n\nexport function encodeAddress(address: Address): Key {\n if (address.length !== 20) {\n throw new TypeError(\n `Address must be 20 bytes long, but got ${address.length} bytes.`,\n );\n }\n return address;\n}\n\nexport function encodeAddressSet(addresses: Set<Address>): Value {\n const array: Address[] = [];\n addresses.forEach((addr) => array.push(addr));\n array.sort(compareUint8Array);\n return array.map(encodeAddress);\n}\n", "import { encode, RecordValue, RecordView, Value } from \"@planetarium/bencodex\";\nimport { Address, encodeAddressSet } from \"./address.js\";\n\nexport interface Currency {\n ticker: string;\n decimalPlaces: number;\n minters: Set<Address> | null;\n totalSupplyTrackable: boolean;\n maximumSupply: {\n major: bigint;\n minor: bigint;\n } | null;\n}\n\nexport function encodeCurrency(currency: Currency): Value {\n const minters: Value =\n currency.minters === null ? null : encodeAddressSet(currency.minters);\n const serialized: RecordValue = {\n ticker: currency.ticker,\n decimalPlaces: new Uint8Array([currency.decimalPlaces]),\n minters,\n };\n\n if (currency.maximumSupply !== null) {\n if (!currency.totalSupplyTrackable) {\n throw new TypeError(\"maximumSupply implies totalSupplyTrackable\");\n }\n\n serialized.maximumSupplyMajor = currency.maximumSupply.major;\n serialized.maximumSupplyMinor = currency.maximumSupply.minor;\n }\n\n if (currency.totalSupplyTrackable) {\n serialized.totalSupplyTrackable = true;\n }\n\n return new RecordView(serialized, \"text\");\n}\n\nfunction encodeCurrencyForHash(currency: Currency): Value {\n const minters: Value =\n currency.minters === null ? null : encodeAddressSet(currency.minters);\n const serialized: RecordValue = {\n ticker: currency.ticker,\n decimals: BigInt(currency.decimalPlaces),\n minters,\n };\n\n if (currency.maximumSupply !== null) {\n if (!currency.totalSupplyTrackable) {\n throw new TypeError(\"maximumSupply implies totalSupplyTrackable\");\n }\n\n serialized.maximumSupplyMajor = currency.maximumSupply.major;\n serialized.maximumSupplyMinor = currency.maximumSupply.minor;\n }\n\n if (currency.totalSupplyTrackable) {\n serialized.totalSupplyTrackable = true;\n }\n\n return new RecordView(serialized, \"text\");\n}\n\nexport async function getCurrencyHash(currency: Currency): Promise<Uint8Array> {\n const encoded = encode(encodeCurrencyForHash(currency));\n const buffer = await crypto.subtle.digest(\"SHA-1\", encoded);\n return new Uint8Array(buffer);\n}\n\nexport interface FungibleAssetValue {\n rawValue: bigint;\n currency: Currency;\n}\n\nexport function encodeFungibleAssetValue(value: FungibleAssetValue): Value[] {\n return [encodeCurrency(value.currency), value.rawValue];\n}\n\nfunction abs(value: bigint): bigint {\n return value < 0n ? -value : value;\n}\n\nexport function getSign(value: FungibleAssetValue): -1 | 0 | 1 {\n return value.rawValue < 0n ? -1 : value.rawValue > 0n ? 1 : 0;\n}\n\nexport function getMajorUnit(value: FungibleAssetValue): bigint {\n return abs(value.rawValue) / 10n ** BigInt(value.currency.decimalPlaces);\n}\n\nexport function getMinorUnit(value: FungibleAssetValue): bigint {\n return abs(value.rawValue) % 10n ** BigInt(value.currency.decimalPlaces);\n}\n", "import {\n BencodexDictionary,\n Dictionary,\n Key,\n Value,\n} from \"@planetarium/bencodex\";\nimport { Address, encodeAddress, encodeAddressSet } from \"../address.js\";\nimport { FungibleAssetValue, encodeFungibleAssetValue } from \"../assets.js\";\nimport { BlockHash, encodeBlockHash } from \"../blockhash.js\";\nimport { encodePublicKey, PublicKey } from \"../key.js\";\n\n/**\n * Represents an unsigned transaction without actions. Corresponds to\n * Libplanet's `TxMetadata`.\n */\nexport interface TxMetadata {\n nonce: bigint;\n publicKey: PublicKey;\n signer: Address; // TODO: This field can be derived from publicKey.\n timestamp: Date;\n updatedAddresses: Set<Address>;\n genesisHash: BlockHash | null;\n gasLimit: bigint | null;\n maxGasPrice: FungibleAssetValue | null;\n}\n\nconst NONCE_KEY = new Uint8Array([0x6e]); // 'n'\nconst SIGNER_KEY = new Uint8Array([0x73]); // 's'\nconst GENESIS_HASH_KEY = new Uint8Array([0x67]); // 'g'\nconst UPDATED_ADDRESSES_KEY = new Uint8Array([0x75]); // 'u'\nconst PUBLIC_KEY_KEY = new Uint8Array([0x70]); // 'p'\nconst TIMESTAMP_KEY = new Uint8Array([0x74]); // 't'\nconst GAS_LIMIT_KEY = new Uint8Array([0x6c]); // 'l'\nconst MAX_GAS_PRICE_KEY = new Uint8Array([0x6d]); // 'm'\n\nexport function encodeTxMetadata(metadata: TxMetadata): Dictionary {\n const updatedAddresses = encodeAddressSet(metadata.updatedAddresses);\n const timestamp = metadata.timestamp.toISOString().replace(/Z$/, \"000Z\");\n const pairs: [Key, Value][] = [\n [NONCE_KEY, metadata.nonce],\n [SIGNER_KEY, encodeAddress(metadata.signer)],\n [UPDATED_ADDRESSES_KEY, updatedAddresses],\n [PUBLIC_KEY_KEY, encodePublicKey(metadata.publicKey)],\n [TIMESTAMP_KEY, timestamp],\n ];\n if (metadata.genesisHash !== null) {\n pairs.push([GENESIS_HASH_KEY, encodeBlockHash(metadata.genesisHash)]);\n }\n if (metadata.gasLimit !== null) {\n pairs.push([GAS_LIMIT_KEY, metadata.gasLimit]);\n }\n if (metadata.maxGasPrice !== null) {\n pairs.push([MAX_GAS_PRICE_KEY, encodeFungibleAssetValue(metadata.maxGasPrice)]);\n }\n\n return new BencodexDictionary(pairs);\n}\n", "import { Value } from \"@planetarium/bencodex\";\n\nexport type BlockHash = Uint8Array; // TODO: proper type definition\n\nexport function encodeBlockHash(blockHash: BlockHash): Value {\n if (blockHash.length !== 32) {\n throw new TypeError(\n `BlockHash must be 32 bytes long, but got ${blockHash.length} bytes.`,\n );\n }\n return blockHash;\n}\n", "import { Value } from \"@planetarium/bencodex\";\n\nexport type PublicKey = Uint8Array; // TODO: proper type definition\n\nexport function encodePublicKey(publicKey: PublicKey): Value {\n if (publicKey.length < 1) {\n throw new TypeError(\"Public key must not be empty.\");\n }\n return publicKey;\n}\n", "import { BencodexDictionary, Dictionary, Value } from \"@planetarium/bencodex\";\nimport { encodeTxMetadata, TxMetadata } from \"./metadata.js\";\n\nconst ACTION_KEY = new Uint8Array([0x61]); // 'a'\n\nexport interface UnsignedTx extends TxMetadata {\n actions: Value[];\n}\n\n/**\n * Encodes an unsigned transaction.\n * @param tx An unsigned transaction.\n * @returns An encoded transaction.\n */\nexport function encodeUnsignedTx(metadata: UnsignedTx): Dictionary {\n return new BencodexDictionary([\n ...encodeTxMetadata(metadata),\n [ACTION_KEY, metadata.actions],\n ]);\n}\n", "import { Account, Address, Signature } from \"@planetarium/account\";\nimport { BencodexDictionary, Dictionary, encode } from \"@planetarium/bencodex\";\nimport { bytesEqual } from \"../bytes.js\";\nimport { type UnsignedTx, encodeUnsignedTx } from \"./unsigned.js\";\n\nconst SIGNATURE_KEY = new Uint8Array([0x53]); // 'S'\n\nexport type SignedTx = UnsignedTx & { signature: Signature };\n\nexport async function signTx(\n tx: UnsignedTx,\n signAccount: Account\n): Promise<SignedTx> {\n if (\n !bytesEqual(\n tx.publicKey,\n (await signAccount.getPublicKey()).toBytes(\"uncompressed\")\n )\n ) {\n throw new Error(\"Public keys in the tx and the signAccount are mismatched\");\n } else if (\n !bytesEqual(\n tx.signer,\n Address.deriveFrom(await signAccount.getPublicKey()).toBytes()\n )\n ) {\n throw new Error(\"The transaction signer does not match to the signAccount\");\n }\n const payload = encodeUnsignedTx(tx);\n const signature = await signAccount.sign(encode(payload));\n return {\n ...tx,\n signature,\n };\n}\n\nexport function encodeSignedTx(tx: SignedTx): Dictionary {\n const dict = encodeUnsignedTx(tx);\n const sig = tx.signature.toBytes();\n return new BencodexDictionary([...dict, [SIGNATURE_KEY, sig]]);\n}\n", "\nexport function bytesEqual(\n a: Uint8Array | ArrayBuffer,\n b: Uint8Array | ArrayBuffer\n): boolean {\n const x = a instanceof ArrayBuffer ? new Uint8Array(a) : a;\n const y = b instanceof ArrayBuffer ? new Uint8Array(b) : b;\n return x.length === y.length && x.every((v, i) => v === y[i]);\n}\n"], "mappings": "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", "names": ["import_bencodex", "import_bencodex", "import_bencodex"] }