@solana/spl-name-service
Version:
SPL Name Service JavaScript API
233 lines • 14 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createReverseTwitterRegistry = exports.ReverseTwitterRegistryState = exports.getTwitterRegistryData = exports.getTwitterHandleandRegistryKeyViaFilters = exports.getHandleAndRegistryKey = exports.getTwitterRegistry = exports.getTwitterRegistryKey = exports.deleteTwitterRegistry = exports.changeVerifiedPubkey = exports.changeTwitterRegistryData = exports.createVerifiedTwitterRegistry = exports.TWITTER_ROOT_PARENT_REGISTRY_KEY = exports.TWITTER_VERIFICATION_AUTHORITY = void 0;
const web3_js_1 = require("@solana/web3.js");
const borsh_1 = require("borsh");
const bindings_1 = require("./bindings");
const instructions_1 = require("./instructions");
const state_1 = require("./state");
const utils_1 = require("./utils");
////////////////////////////////////////////////////
// Global Variables
exports.TWITTER_VERIFICATION_AUTHORITY = new web3_js_1.PublicKey('FvPH7PrVrLGKPfqaf3xJodFTjZriqrAXXLTVWEorTFBi');
// The address of the name registry that will be a parent to all twitter handle registries,
// it should be owned by the TWITTER_VERIFICATION_AUTHORITY and its name is irrelevant
exports.TWITTER_ROOT_PARENT_REGISTRY_KEY = new web3_js_1.PublicKey('4YcexoW3r78zz16J2aqmukBLRwGq6rAvWzJpkYAXqebv');
////////////////////////////////////////////////////
// Bindings
// Signed by the authority, the payer and the verified pubkey
function createVerifiedTwitterRegistry(connection, twitterHandle, verifiedPubkey, space, // The space that the user will have to write data into the verified registry
payerKey) {
return __awaiter(this, void 0, void 0, function* () {
// Create user facing registry
const hashedTwitterHandle = yield (0, utils_1.getHashedName)(twitterHandle);
const twitterHandleRegistryKey = yield (0, utils_1.getNameAccountKey)(hashedTwitterHandle, undefined, exports.TWITTER_ROOT_PARENT_REGISTRY_KEY);
let instructions = [
(0, instructions_1.createInstruction)(bindings_1.NAME_PROGRAM_ID, web3_js_1.SystemProgram.programId, twitterHandleRegistryKey, verifiedPubkey, payerKey, hashedTwitterHandle, new utils_1.Numberu64(yield connection.getMinimumBalanceForRentExemption(space)), new utils_1.Numberu32(space), undefined, exports.TWITTER_ROOT_PARENT_REGISTRY_KEY, exports.TWITTER_VERIFICATION_AUTHORITY),
];
instructions = instructions.concat(yield createReverseTwitterRegistry(connection, twitterHandle, twitterHandleRegistryKey, verifiedPubkey, payerKey));
return instructions;
});
}
exports.createVerifiedTwitterRegistry = createVerifiedTwitterRegistry;
// Overwrite the data that is written in the user facing registry
// Signed by the verified pubkey
function changeTwitterRegistryData(twitterHandle, verifiedPubkey, offset, // The offset at which to write the input data into the NameRegistryData
input_data) {
return __awaiter(this, void 0, void 0, function* () {
const hashedTwitterHandle = yield (0, utils_1.getHashedName)(twitterHandle);
const twitterHandleRegistryKey = yield (0, utils_1.getNameAccountKey)(hashedTwitterHandle, undefined, exports.TWITTER_ROOT_PARENT_REGISTRY_KEY);
const instructions = [
(0, instructions_1.updateInstruction)(bindings_1.NAME_PROGRAM_ID, twitterHandleRegistryKey, new utils_1.Numberu32(offset), input_data, verifiedPubkey, undefined),
];
return instructions;
});
}
exports.changeTwitterRegistryData = changeTwitterRegistryData;
// Change the verified pubkey for a given twitter handle
// Signed by the Authority, the verified pubkey and the payer
function changeVerifiedPubkey(connection, twitterHandle, currentVerifiedPubkey, newVerifiedPubkey, payerKey) {
return __awaiter(this, void 0, void 0, function* () {
const hashedTwitterHandle = yield (0, utils_1.getHashedName)(twitterHandle);
const twitterHandleRegistryKey = yield (0, utils_1.getNameAccountKey)(hashedTwitterHandle, undefined, exports.TWITTER_ROOT_PARENT_REGISTRY_KEY);
// Transfer the user-facing registry ownership
let instructions = [
(0, instructions_1.transferInstruction)(bindings_1.NAME_PROGRAM_ID, twitterHandleRegistryKey, newVerifiedPubkey, currentVerifiedPubkey, undefined),
];
// Delete the current reverse registry
instructions.push(yield (0, bindings_1.deleteNameRegistry)(connection, currentVerifiedPubkey.toString(), payerKey, exports.TWITTER_VERIFICATION_AUTHORITY, exports.TWITTER_ROOT_PARENT_REGISTRY_KEY));
// Create the new reverse registry
instructions = instructions.concat(yield createReverseTwitterRegistry(connection, twitterHandle, twitterHandleRegistryKey, newVerifiedPubkey, payerKey));
return instructions;
});
}
exports.changeVerifiedPubkey = changeVerifiedPubkey;
// Delete the verified registry for a given twitter handle
// Signed by the verified pubkey
function deleteTwitterRegistry(twitterHandle, verifiedPubkey) {
return __awaiter(this, void 0, void 0, function* () {
const hashedTwitterHandle = yield (0, utils_1.getHashedName)(twitterHandle);
const twitterHandleRegistryKey = yield (0, utils_1.getNameAccountKey)(hashedTwitterHandle, undefined, exports.TWITTER_ROOT_PARENT_REGISTRY_KEY);
const hashedVerifiedPubkey = yield (0, utils_1.getHashedName)(verifiedPubkey.toString());
const reverseRegistryKey = yield (0, utils_1.getNameAccountKey)(hashedVerifiedPubkey, exports.TWITTER_VERIFICATION_AUTHORITY, exports.TWITTER_ROOT_PARENT_REGISTRY_KEY);
const instructions = [
// Delete the user facing registry
(0, instructions_1.deleteInstruction)(bindings_1.NAME_PROGRAM_ID, twitterHandleRegistryKey, verifiedPubkey, verifiedPubkey),
// Delete the reverse registry
(0, instructions_1.deleteInstruction)(bindings_1.NAME_PROGRAM_ID, reverseRegistryKey, verifiedPubkey, verifiedPubkey),
];
return instructions;
});
}
exports.deleteTwitterRegistry = deleteTwitterRegistry;
//////////////////////////////////////////
// Getter Functions
// Returns the key of the user-facing registry
function getTwitterRegistryKey(twitter_handle) {
return __awaiter(this, void 0, void 0, function* () {
const hashedTwitterHandle = yield (0, utils_1.getHashedName)(twitter_handle);
return yield (0, utils_1.getNameAccountKey)(hashedTwitterHandle, undefined, exports.TWITTER_ROOT_PARENT_REGISTRY_KEY);
});
}
exports.getTwitterRegistryKey = getTwitterRegistryKey;
function getTwitterRegistry(connection, twitter_handle) {
return __awaiter(this, void 0, void 0, function* () {
const hashedTwitterHandle = yield (0, utils_1.getHashedName)(twitter_handle);
const twitterHandleRegistryKey = yield (0, utils_1.getNameAccountKey)(hashedTwitterHandle, undefined, exports.TWITTER_ROOT_PARENT_REGISTRY_KEY);
const registry = state_1.NameRegistryState.retrieve(connection, twitterHandleRegistryKey);
return registry;
});
}
exports.getTwitterRegistry = getTwitterRegistry;
function getHandleAndRegistryKey(connection, verifiedPubkey) {
return __awaiter(this, void 0, void 0, function* () {
const hashedVerifiedPubkey = yield (0, utils_1.getHashedName)(verifiedPubkey.toString());
const reverseRegistryKey = yield (0, utils_1.getNameAccountKey)(hashedVerifiedPubkey, exports.TWITTER_VERIFICATION_AUTHORITY, exports.TWITTER_ROOT_PARENT_REGISTRY_KEY);
const reverseRegistryState = yield ReverseTwitterRegistryState.retrieve(connection, reverseRegistryKey);
return [
reverseRegistryState.twitterHandle,
new web3_js_1.PublicKey(reverseRegistryState.twitterRegistryKey),
];
});
}
exports.getHandleAndRegistryKey = getHandleAndRegistryKey;
// Uses the RPC node filtering feature, execution speed may vary
function getTwitterHandleandRegistryKeyViaFilters(connection, verifiedPubkey) {
return __awaiter(this, void 0, void 0, function* () {
const filters = [
{
memcmp: {
offset: 0,
bytes: exports.TWITTER_ROOT_PARENT_REGISTRY_KEY.toBase58(),
},
},
{
memcmp: {
offset: 32,
bytes: verifiedPubkey.toBase58(),
},
},
{
memcmp: {
offset: 64,
bytes: exports.TWITTER_VERIFICATION_AUTHORITY.toBase58(),
},
},
];
const filteredAccounts = yield (0, utils_1.getFilteredProgramAccounts)(connection, bindings_1.NAME_PROGRAM_ID, filters);
for (const f of filteredAccounts) {
if (f.accountInfo.data.length > state_1.NameRegistryState.HEADER_LEN + 32) {
const data = f.accountInfo.data.slice(state_1.NameRegistryState.HEADER_LEN);
const state = (0, borsh_1.deserialize)(ReverseTwitterRegistryState.schema, data);
return [state.twitterHandle, new web3_js_1.PublicKey(state.twitterRegistryKey)];
}
}
throw new Error('Registry not found.');
});
}
exports.getTwitterHandleandRegistryKeyViaFilters = getTwitterHandleandRegistryKeyViaFilters;
// Uses the RPC node filtering feature, execution speed may vary
// Does not give you the handle, but is an alternative to getHandlesAndKeysFromVerifiedPubkey + getTwitterRegistry to get the data
function getTwitterRegistryData(connection, verifiedPubkey) {
return __awaiter(this, void 0, void 0, function* () {
const filters = [
{
memcmp: {
offset: 0,
bytes: exports.TWITTER_ROOT_PARENT_REGISTRY_KEY.toBase58(),
},
},
{
memcmp: {
offset: 32,
bytes: verifiedPubkey.toBase58(),
},
},
{
memcmp: {
offset: 64,
bytes: new web3_js_1.PublicKey(Buffer.alloc(32, 0)).toBase58(),
},
},
];
const filteredAccounts = yield (0, utils_1.getFilteredProgramAccounts)(connection, bindings_1.NAME_PROGRAM_ID, filters);
if (filteredAccounts.length > 1) {
throw new Error('Found more than one registry.');
}
return filteredAccounts[0].accountInfo.data.slice(state_1.NameRegistryState.HEADER_LEN);
});
}
exports.getTwitterRegistryData = getTwitterRegistryData;
//////////////////////////////////////////////
// Utils
class ReverseTwitterRegistryState {
constructor(obj) {
this.twitterRegistryKey = obj.twitterRegistryKey;
this.twitterHandle = obj.twitterHandle;
}
static retrieve(connection, reverseTwitterAccountKey) {
return __awaiter(this, void 0, void 0, function* () {
const reverseTwitterAccount = yield connection.getAccountInfo(reverseTwitterAccountKey, 'processed');
if (!reverseTwitterAccount) {
throw new Error('Invalid reverse Twitter account provided');
}
const res = (0, borsh_1.deserialize)(this.schema, reverseTwitterAccount.data.slice(state_1.NameRegistryState.HEADER_LEN));
return res;
});
}
}
exports.ReverseTwitterRegistryState = ReverseTwitterRegistryState;
ReverseTwitterRegistryState.schema = {
struct: {
twitterRegistryKey: { array: { type: 'u8', len: 32 } },
twitterHandle: 'string',
},
};
function createReverseTwitterRegistry(connection, twitterHandle, twitterRegistryKey, verifiedPubkey, payerKey) {
return __awaiter(this, void 0, void 0, function* () {
// Create the reverse lookup registry
const hashedVerifiedPubkey = yield (0, utils_1.getHashedName)(verifiedPubkey.toString());
const reverseRegistryKey = yield (0, utils_1.getNameAccountKey)(hashedVerifiedPubkey, exports.TWITTER_VERIFICATION_AUTHORITY, exports.TWITTER_ROOT_PARENT_REGISTRY_KEY);
const reverseTwitterRegistryStateBuff = (0, borsh_1.serialize)(ReverseTwitterRegistryState.schema, new ReverseTwitterRegistryState({
twitterRegistryKey: twitterRegistryKey.toBytes(),
twitterHandle,
}));
return [
(0, instructions_1.createInstruction)(bindings_1.NAME_PROGRAM_ID, web3_js_1.SystemProgram.programId, reverseRegistryKey, verifiedPubkey, payerKey, hashedVerifiedPubkey, new utils_1.Numberu64(yield connection.getMinimumBalanceForRentExemption(reverseTwitterRegistryStateBuff.length)), new utils_1.Numberu32(reverseTwitterRegistryStateBuff.length), exports.TWITTER_VERIFICATION_AUTHORITY, // Twitter authority acts as class for all reverse-lookup registries
exports.TWITTER_ROOT_PARENT_REGISTRY_KEY, // Reverse registries are also children of the root
exports.TWITTER_VERIFICATION_AUTHORITY),
(0, instructions_1.updateInstruction)(bindings_1.NAME_PROGRAM_ID, reverseRegistryKey, new utils_1.Numberu32(0), Buffer.from(reverseTwitterRegistryStateBuff), exports.TWITTER_VERIFICATION_AUTHORITY, undefined),
];
});
}
exports.createReverseTwitterRegistry = createReverseTwitterRegistry;
//# sourceMappingURL=twitter.js.map