UNPKG

@stacks/bns

Version:

Library for working with the Stacks Blockchain Naming System BNS.

328 lines 14.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BNS_CONTRACT_NAME = void 0; exports.canRegisterName = canRegisterName; exports.getNamespacePrice = getNamespacePrice; exports.getNamePrice = getNamePrice; exports.buildPreorderNamespaceTx = buildPreorderNamespaceTx; exports.buildRevealNamespaceTx = buildRevealNamespaceTx; exports.buildImportNameTx = buildImportNameTx; exports.buildReadyNamespaceTx = buildReadyNamespaceTx; exports.buildPreorderNameTx = buildPreorderNameTx; exports.buildRegisterNameTx = buildRegisterNameTx; exports.buildUpdateNameTx = buildUpdateNameTx; exports.buildTransferNameTx = buildTransferNameTx; exports.buildRevokeNameTx = buildRevokeNameTx; exports.buildRenewNameTx = buildRenewNameTx; const common_1 = require("@stacks/common"); const transactions_1 = require("@stacks/transactions"); const utils_1 = require("./utils"); exports.BNS_CONTRACT_NAME = 'bns'; async function makeBnsContractCall(options) { const txOptions = { contractAddress: options.network.bootAddress, contractName: exports.BNS_CONTRACT_NAME, functionName: options.functionName, functionArgs: options.functionArgs, publicKey: options.publicKey, validateWithAbi: false, network: options.network, postConditions: options.postConditions, }; return (0, transactions_1.makeUnsignedContractCall)(txOptions); } async function callReadOnlyBnsFunction(options) { return (0, transactions_1.fetchCallReadOnlyFunction)({ ...options, contractAddress: options.network.bootAddress, contractName: exports.BNS_CONTRACT_NAME, }); } async function canRegisterName({ fullyQualifiedName, network, }) { const bnsFunctionName = 'can-name-be-registered'; const { subdomain, namespace, name } = (0, utils_1.decodeFQN)(fullyQualifiedName); if (subdomain) { throw new Error('Cannot register a subdomain using registerName'); } const randomPrivateKey = (0, transactions_1.makeRandomPrivKey)(); const randomAddress = (0, transactions_1.getAddressFromPrivateKey)(randomPrivateKey); return callReadOnlyBnsFunction({ functionName: bnsFunctionName, senderAddress: randomAddress, functionArgs: [(0, transactions_1.bufferCVFromString)(namespace), (0, transactions_1.bufferCVFromString)(name)], network, }).then((responseCV) => { if (responseCV.type === transactions_1.ClarityType.ResponseOk) { return responseCV.value.type === transactions_1.ClarityType.BoolTrue; } else { return false; } }); } async function getNamespacePrice({ namespace, network, }) { const bnsFunctionName = 'get-namespace-price'; const randomPrivateKey = (0, transactions_1.makeRandomPrivKey)(); const randomAddress = (0, transactions_1.getAddressFromPrivateKey)(randomPrivateKey); return callReadOnlyBnsFunction({ functionName: bnsFunctionName, senderAddress: randomAddress, functionArgs: [(0, transactions_1.bufferCVFromString)(namespace)], network, }).then((responseCV) => { if (responseCV.type === transactions_1.ClarityType.ResponseOk) { if (responseCV.value.type === transactions_1.ClarityType.Int || responseCV.value.type === transactions_1.ClarityType.UInt) { return BigInt(responseCV.value.value); } else { throw new Error('Response did not contain a number'); } } else if (responseCV.type === transactions_1.ClarityType.ResponseErr) { throw new Error((0, transactions_1.cvToString)(responseCV.value)); } else { throw new Error(`Unexpected Clarity Value type: ${(0, transactions_1.getCVTypeString)(responseCV)}`); } }); } async function getNamePrice({ fullyQualifiedName, network, }) { const bnsFunctionName = 'get-name-price'; const { subdomain, namespace, name } = (0, utils_1.decodeFQN)(fullyQualifiedName); if (subdomain) { throw new Error('Cannot get subdomain name price'); } const randomPrivateKey = (0, transactions_1.makeRandomPrivKey)(); const randomAddress = (0, transactions_1.getAddressFromPrivateKey)(randomPrivateKey); return callReadOnlyBnsFunction({ functionName: bnsFunctionName, senderAddress: randomAddress, functionArgs: [(0, transactions_1.bufferCVFromString)(namespace), (0, transactions_1.bufferCVFromString)(name)], network, }).then((responseCV) => { if (responseCV.type === transactions_1.ClarityType.ResponseOk) { if (responseCV.value.type === transactions_1.ClarityType.Int || responseCV.value.type === transactions_1.ClarityType.UInt) { return BigInt(responseCV.value.value); } else { throw new Error('Response did not contain a number'); } } else { const errorResponse = responseCV; throw new Error((0, transactions_1.cvToString)(errorResponse.value)); } }); } async function buildPreorderNamespaceTx({ namespace, salt, stxToBurn, publicKey, network, }) { const bnsFunctionName = 'namespace-preorder'; const saltedNamespaceBytes = (0, common_1.utf8ToBytes)(`${namespace}${salt}`); const hashedSaltedNamespace = (0, transactions_1.hash160)(saltedNamespaceBytes); const burnSTXPostCondition = { type: 'stx-postcondition', address: (0, transactions_1.publicKeyToAddress)(network.addressVersion.singleSig, publicKey), condition: 'eq', amount: (0, common_1.intToBigInt)(stxToBurn), }; return makeBnsContractCall({ functionName: bnsFunctionName, functionArgs: [(0, transactions_1.bufferCV)(hashedSaltedNamespace), (0, transactions_1.uintCV)(stxToBurn)], publicKey, network, postConditions: [burnSTXPostCondition], }); } async function buildRevealNamespaceTx({ namespace, salt, priceFunction, lifetime, namespaceImportAddress, publicKey, network, }) { const bnsFunctionName = 'namespace-reveal'; return makeBnsContractCall({ functionName: bnsFunctionName, functionArgs: [ (0, transactions_1.bufferCVFromString)(namespace), (0, transactions_1.bufferCVFromString)(salt), (0, transactions_1.uintCV)(priceFunction.base), (0, transactions_1.uintCV)(priceFunction.coefficient), (0, transactions_1.uintCV)(priceFunction.b1), (0, transactions_1.uintCV)(priceFunction.b2), (0, transactions_1.uintCV)(priceFunction.b3), (0, transactions_1.uintCV)(priceFunction.b4), (0, transactions_1.uintCV)(priceFunction.b5), (0, transactions_1.uintCV)(priceFunction.b6), (0, transactions_1.uintCV)(priceFunction.b7), (0, transactions_1.uintCV)(priceFunction.b8), (0, transactions_1.uintCV)(priceFunction.b9), (0, transactions_1.uintCV)(priceFunction.b10), (0, transactions_1.uintCV)(priceFunction.b11), (0, transactions_1.uintCV)(priceFunction.b12), (0, transactions_1.uintCV)(priceFunction.b13), (0, transactions_1.uintCV)(priceFunction.b14), (0, transactions_1.uintCV)(priceFunction.b15), (0, transactions_1.uintCV)(priceFunction.b16), (0, transactions_1.uintCV)(priceFunction.nonAlphaDiscount), (0, transactions_1.uintCV)(priceFunction.noVowelDiscount), (0, transactions_1.uintCV)(lifetime), (0, transactions_1.standardPrincipalCV)(namespaceImportAddress), ], publicKey, network, }); } async function buildImportNameTx({ namespace, name, beneficiary, zonefile, publicKey, network, }) { const bnsFunctionName = 'name-import'; const zonefileHash = (0, utils_1.getZonefileHash)(zonefile); return makeBnsContractCall({ functionName: bnsFunctionName, functionArgs: [ (0, transactions_1.bufferCVFromString)(namespace), (0, transactions_1.bufferCVFromString)(name), (0, transactions_1.standardPrincipalCV)(beneficiary), (0, transactions_1.bufferCV)(zonefileHash), ], publicKey, network, }); } async function buildReadyNamespaceTx({ namespace, publicKey, network, }) { const bnsFunctionName = 'namespace-ready'; return makeBnsContractCall({ functionName: bnsFunctionName, functionArgs: [(0, transactions_1.bufferCVFromString)(namespace)], publicKey, network, }); } async function buildPreorderNameTx({ fullyQualifiedName, salt, stxToBurn, publicKey, network, }) { const bnsFunctionName = 'name-preorder'; const { subdomain } = (0, utils_1.decodeFQN)(fullyQualifiedName); if (subdomain) { throw new Error('Cannot preorder a subdomain using preorderName()'); } const saltedNamesBytes = (0, common_1.utf8ToBytes)(`${fullyQualifiedName}${salt}`); const hashedSaltedName = (0, transactions_1.hash160)(saltedNamesBytes); const burnSTXPostCondition = { type: 'stx-postcondition', address: (0, transactions_1.publicKeyToAddress)(network.addressVersion.singleSig, publicKey), condition: 'eq', amount: (0, common_1.intToBigInt)(stxToBurn), }; return makeBnsContractCall({ functionName: bnsFunctionName, functionArgs: [(0, transactions_1.bufferCV)(hashedSaltedName), (0, transactions_1.uintCV)(stxToBurn)], publicKey, network, postConditions: [burnSTXPostCondition], }); } async function buildRegisterNameTx({ fullyQualifiedName, salt, zonefile, publicKey, network, }) { const bnsFunctionName = 'name-register'; const { subdomain, namespace, name } = (0, utils_1.decodeFQN)(fullyQualifiedName); if (subdomain) { throw new Error('Cannot register a subdomain using registerName()'); } const zonefileHash = (0, utils_1.getZonefileHash)(zonefile); return makeBnsContractCall({ functionName: bnsFunctionName, functionArgs: [ (0, transactions_1.bufferCVFromString)(namespace), (0, transactions_1.bufferCVFromString)(name), (0, transactions_1.bufferCVFromString)(salt), (0, transactions_1.bufferCV)(zonefileHash), ], network, publicKey, }); } async function buildUpdateNameTx({ fullyQualifiedName, zonefile, publicKey, network, }) { const bnsFunctionName = 'name-update'; const { subdomain, namespace, name } = (0, utils_1.decodeFQN)(fullyQualifiedName); if (subdomain) { throw new Error('Cannot update a subdomain using updateName()'); } const zonefileHash = (0, utils_1.getZonefileHash)(zonefile); return makeBnsContractCall({ functionName: bnsFunctionName, functionArgs: [(0, transactions_1.bufferCVFromString)(namespace), (0, transactions_1.bufferCVFromString)(name), (0, transactions_1.bufferCV)(zonefileHash)], publicKey, network, }); } async function buildTransferNameTx({ fullyQualifiedName, newOwnerAddress, zonefile, publicKey, network, }) { const bnsFunctionName = 'name-transfer'; const { subdomain, namespace, name } = (0, utils_1.decodeFQN)(fullyQualifiedName); if (subdomain) { throw new Error('Cannot transfer a subdomain using transferName()'); } const functionArgs = [ (0, transactions_1.bufferCVFromString)(namespace), (0, transactions_1.bufferCVFromString)(name), (0, transactions_1.standardPrincipalCV)(newOwnerAddress), zonefile ? (0, transactions_1.someCV)((0, transactions_1.bufferCV)((0, utils_1.getZonefileHash)(zonefile))) : (0, transactions_1.noneCV)(), ]; const postConditionSender = { type: 'nft-postcondition', address: (0, transactions_1.publicKeyToAddress)(network.addressVersion.singleSig, publicKey), condition: 'sent', asset: `${network.bootAddress}.bns::names`, assetId: (0, transactions_1.tupleCV)({ name: (0, transactions_1.bufferCVFromString)(name), namespace: (0, transactions_1.bufferCVFromString)(namespace), }), }; const postConditionReceiver = { type: 'nft-postcondition', address: newOwnerAddress, condition: 'not-sent', asset: `${network.bootAddress}.bns::names`, assetId: (0, transactions_1.tupleCV)({ name: (0, transactions_1.bufferCVFromString)(name), namespace: (0, transactions_1.bufferCVFromString)(namespace), }), }; return makeBnsContractCall({ functionName: bnsFunctionName, functionArgs, publicKey, network, postConditions: [postConditionSender, postConditionReceiver], }); } async function buildRevokeNameTx({ fullyQualifiedName, publicKey, network, }) { const bnsFunctionName = 'name-revoke'; const { subdomain, namespace, name } = (0, utils_1.decodeFQN)(fullyQualifiedName); if (subdomain) { throw new Error('Cannot revoke a subdomain using revokeName()'); } return makeBnsContractCall({ functionName: bnsFunctionName, functionArgs: [(0, transactions_1.bufferCVFromString)(namespace), (0, transactions_1.bufferCVFromString)(name)], publicKey, network, }); } async function buildRenewNameTx({ fullyQualifiedName, stxToBurn, newOwnerAddress, zonefile, publicKey, network, }) { const bnsFunctionName = 'name-renewal'; const { subdomain, namespace, name } = (0, utils_1.decodeFQN)(fullyQualifiedName); if (subdomain) { throw new Error('Cannot renew a subdomain using renewName()'); } const functionArgs = [ (0, transactions_1.bufferCVFromString)(namespace), (0, transactions_1.bufferCVFromString)(name), (0, transactions_1.uintCV)(stxToBurn), newOwnerAddress ? (0, transactions_1.someCV)((0, transactions_1.standardPrincipalCV)(newOwnerAddress)) : (0, transactions_1.noneCV)(), zonefile ? (0, transactions_1.someCV)((0, transactions_1.bufferCV)((0, utils_1.getZonefileHash)(zonefile))) : (0, transactions_1.noneCV)(), ]; const burnSTXPostCondition = { type: 'stx-postcondition', address: (0, transactions_1.publicKeyToAddress)(network.addressVersion.singleSig, publicKey), condition: 'eq', amount: (0, common_1.intToBigInt)(stxToBurn), }; return makeBnsContractCall({ functionName: bnsFunctionName, functionArgs, publicKey, network, postConditions: [burnSTXPostCondition], }); } //# sourceMappingURL=index.js.map