SHA256
Сократить promo-аргументы регистрации в Solana
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { base64ToBytes, bytesToBase58, importPkcs8Ed25519, sha256Bytes, signBytes } from './crypto-utils.js';
|
||||
import { base58ToBytes, base64ToBytes, bytesToBase58, importPkcs8Ed25519, sha256Bytes, signBytes } from './crypto-utils.js';
|
||||
import { extractSeed32FromPkcs8B64 } from './client-key-utils.js';
|
||||
import {
|
||||
SHINE_LOGIN_GUARD_PROGRAM_ID,
|
||||
@@ -216,9 +216,9 @@ function serializeCreateUserPdaArgs(args) {
|
||||
}
|
||||
buf.push(Number(args.trustedCount || 0) & 0xff);
|
||||
for (const x of args.rootSignature64) buf.push(x);
|
||||
const promoCode = String(args.promoCode || '').trim();
|
||||
if (promoCode) {
|
||||
pushStrU8(buf, promoCode);
|
||||
const promoSellerLogin = normalizeLogin(String(args.promoSellerLogin || '').trim());
|
||||
if (promoSellerLogin) {
|
||||
pushStrU8(buf, promoSellerLogin);
|
||||
}
|
||||
return new Uint8Array(buf);
|
||||
}
|
||||
@@ -860,6 +860,39 @@ async function createShineUserPdaOnSolana({
|
||||
const unsignedHash = await sha256Bytes(unsignedRecord);
|
||||
const rootSig64 = await signBytes(ctx.rootPrivKey, unsignedHash);
|
||||
|
||||
let promoSellerPda = null;
|
||||
let promoEd25519Ix = null;
|
||||
let promoSellerLogin = '';
|
||||
if (cleanPromoCode) {
|
||||
const dashPos = cleanPromoCode.indexOf('-');
|
||||
if (!cleanPromoCode.startsWith('1') || dashPos <= 1 || dashPos === cleanPromoCode.length - 1) {
|
||||
throw new Error('Некорректный формат промокода');
|
||||
}
|
||||
const sellerLogin = normalizeLogin(cleanPromoCode.slice(1, dashPos));
|
||||
const signatureBase58 = cleanPromoCode.slice(dashPos + 1);
|
||||
promoSellerLogin = sellerLogin;
|
||||
const [promoSellerAddress] = ctx.solana.PublicKey.findProgramAddressSync(
|
||||
[new TextEncoder().encode(SHINE_USERS_PROMO_SELLER_PDA_SEED_PREFIX), new TextEncoder().encode(sellerLogin)],
|
||||
ctx.usersProgram,
|
||||
);
|
||||
promoSellerPda = promoSellerAddress;
|
||||
|
||||
const promoMessage = buildPromoMessageBytes(cleanLogin);
|
||||
const signatureBytes = base58ToBytes(signatureBase58);
|
||||
if (signatureBytes.length !== 64) {
|
||||
throw new Error('Подпись промокода должна быть 64 байта в Base58');
|
||||
}
|
||||
const sellerAccount = await ctx.connection.getAccountInfo(promoSellerAddress, 'confirmed');
|
||||
if (!sellerAccount?.data || sellerAccount.data.length < 42) {
|
||||
throw new Error('Promo seller PDA не найдена или повреждена');
|
||||
}
|
||||
const signerPubkey = new Uint8Array(sellerAccount.data.slice(10, 42));
|
||||
promoEd25519Ix = new ctx.solana.TransactionInstruction({
|
||||
programId: ctx.ed25519Program,
|
||||
keys: [],
|
||||
data: buildEd25519IxData(signatureBytes, signerPubkey, promoMessage),
|
||||
});
|
||||
}
|
||||
const ixData = serializeCreateUserPdaArgs({
|
||||
login: cleanLogin,
|
||||
recoveryKey32: ctx.recoveryKey32,
|
||||
@@ -884,41 +917,9 @@ async function createShineUserPdaOnSolana({
|
||||
sessions: [],
|
||||
trustedCount: 0,
|
||||
rootSignature64: rootSig64,
|
||||
promoCode: cleanPromoCode,
|
||||
promoSellerLogin,
|
||||
});
|
||||
|
||||
let promoSellerPda = null;
|
||||
let promoEd25519Ix = null;
|
||||
if (cleanPromoCode) {
|
||||
const dashPos = cleanPromoCode.indexOf('-');
|
||||
if (!cleanPromoCode.startsWith('1') || dashPos <= 1 || dashPos === cleanPromoCode.length - 1) {
|
||||
throw new Error('Некорректный формат промокода');
|
||||
}
|
||||
const sellerLogin = normalizeLogin(cleanPromoCode.slice(1, dashPos));
|
||||
const signatureBase58 = cleanPromoCode.slice(dashPos + 1);
|
||||
const [promoSellerAddress] = ctx.solana.PublicKey.findProgramAddressSync(
|
||||
[new TextEncoder().encode(SHINE_USERS_PROMO_SELLER_PDA_SEED_PREFIX), new TextEncoder().encode(sellerLogin)],
|
||||
ctx.usersProgram,
|
||||
);
|
||||
promoSellerPda = promoSellerAddress;
|
||||
|
||||
const promoMessage = buildPromoMessageBytes(cleanLogin);
|
||||
const signatureBytes = ctx.solana.bs58.decode(signatureBase58);
|
||||
if (signatureBytes.length !== 64) {
|
||||
throw new Error('Подпись промокода должна быть 64 байта в Base58');
|
||||
}
|
||||
const sellerAccount = await ctx.connection.getAccountInfo(promoSellerAddress, 'confirmed');
|
||||
if (!sellerAccount?.data || sellerAccount.data.length < 42) {
|
||||
throw new Error('Promo seller PDA не найдена или повреждена');
|
||||
}
|
||||
const signerPubkey = new Uint8Array(sellerAccount.data.slice(10, 42));
|
||||
promoEd25519Ix = new ctx.solana.TransactionInstruction({
|
||||
programId: ctx.ed25519Program,
|
||||
keys: [],
|
||||
data: buildEd25519IxData(signatureBytes, signerPubkey, promoMessage),
|
||||
});
|
||||
}
|
||||
|
||||
const ed25519RootIx = new ctx.solana.TransactionInstruction({
|
||||
programId: ctx.ed25519Program,
|
||||
keys: [],
|
||||
|
||||
Reference in New Issue
Block a user