UNPKG

@civic/sol-did-client

Version:
219 lines 9 kB
"use strict"; 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.DidSolTransactionBuilder = exports.DidSolEthSignStatusType = void 0; const web3_js_1 = require("@solana/web3.js"); const anchor_1 = require("@coral-xyz/anchor"); const utils_1 = require("../lib/utils"); const const_1 = require("../lib/const"); const DidAccountSizeHelper_1 = require("../DidAccountSizeHelper"); var DidSolEthSignStatusType; (function (DidSolEthSignStatusType) { DidSolEthSignStatusType[DidSolEthSignStatusType["NotSupported"] = 0] = "NotSupported"; DidSolEthSignStatusType[DidSolEthSignStatusType["Unsigned"] = 1] = "Unsigned"; DidSolEthSignStatusType[DidSolEthSignStatusType["Signed"] = 2] = "Signed"; })(DidSolEthSignStatusType || (exports.DidSolEthSignStatusType = DidSolEthSignStatusType = {})); /** * */ class DidSolTransactionBuilder { constructor(_wallet, _connection, _confirmOptions, idl, _partialSigners = [], _ethSigner, _payer, _resizeAuthority = _wallet.publicKey) { this._wallet = _wallet; this._connection = _connection; this._confirmOptions = _confirmOptions; this._partialSigners = _partialSigners; this._ethSigner = _ethSigner; this._payer = _payer; this._resizeAuthority = _resizeAuthority; // General instructions (that modify the account state only). this._generalInstructions = []; // Generic Instructions that are appended to the instuction list this._postInstructions = []; this._initialWallet = _wallet; this._idlErrors = (0, anchor_1.parseIdlErrors)(idl); } get solWallet() { return this._wallet; } get connection() { return this._connection; } get confirmOptions() { return this._confirmOptions; } get ethSigner() { return this._ethSigner; } withEthSigner(ethSigner) { this._ethSigner = ethSigner; return this; } setInitInstruction(initInstruction) { if (this._initInstruction) { throw new Error('Init instruction already set.'); } this._initInstruction = initInstruction; } setResizeInstruction(resizeInstruction) { if (this._resizeInstruction) { throw new Error('Resize instruction already set.'); } this._resizeInstruction = resizeInstruction; } setCloseInstruction(closeInstruction) { if (this._closeInstruction) { throw new Error('Close instruction already set.'); } this._closeInstruction = closeInstruction; } addGeneralInstruction(instruction) { this._generalInstructions.push(instruction); } addPostInstruction(instruction) { this._postInstructions.push(instruction); } /** * Clears all prepared Instructions and partialSigners, ethWallet, payer and resizeAuthority. */ clear() { this.clearInstructions(); this._wallet = this._initialWallet; this._partialSigners = []; this._ethSigner = undefined; this._payer = undefined; this._resizeAuthority = this._wallet.publicKey; } clearInstructions() { this._initInstruction = undefined; this._resizeInstruction = undefined; this._closeInstruction = undefined; this._generalInstructions = []; this._postInstructions = []; } withConnection(connection) { this._connection = connection; return this; } withConfirmOptions(confirmOptions) { this._confirmOptions = confirmOptions; return this; } withSolWallet(wallet) { this._wallet = wallet; return this; } withAutomaticAlloc(payer, resizeAuthority = this._wallet.publicKey) { this._payer = payer; this._resizeAuthority = resizeAuthority; return this; } withPartialSigners(...signers) { this._partialSigners = signers; return this; } /** * Signs a supported DidSol Instruction with an Ethereum Signer. */ ethSignInstructions(instructionsToSign) { return __awaiter(this, void 0, void 0, function* () { let lastNonce = yield this.getNonce(); const promises = instructionsToSign.map((instruction) => __awaiter(this, void 0, void 0, function* () { if (!this.ethSigner || instruction.ethSignStatus !== DidSolEthSignStatusType.Unsigned) { return instruction.instructionPromise; } const signingNonce = lastNonce; lastNonce = lastNonce.addn(1); return (0, utils_1.ethSignPayload)(yield instruction.instructionPromise, signingNonce, this.ethSigner); })); // Mix in _postInstructions to array. Consider moving to cleaner position return Promise.all([...promises, ...this._postInstructions]); }); } getMaxRequiredSize(currentAccount, currentSize) { let current = [currentAccount, currentSize]; let maxSize = currentSize; for (const instruction of this._generalInstructions) { current = instruction.didAccountChangeCallback(current[0], current[1]); maxSize = Math.max(maxSize, current[1]); } return maxSize; } setAllocInstruction() { return __awaiter(this, void 0, void 0, function* () { if (!this._payer || this._generalInstructions.length === 0) { return; } const [didAccount, didAccountSize] = yield this.getDidAccountWithSize(); if (didAccount === null) { // Initial allocation const requiredSize = this.getMaxRequiredSize((0, DidAccountSizeHelper_1.getDefaultRawDidSolDataAccount)(this.didDataAccount), const_1.INITIAL_MIN_ACCOUNT_SIZE); this.initialize(requiredSize, this._payer); } else { // Reallocation const requiredSize = this.getMaxRequiredSize(didAccount.raw, DidAccountSizeHelper_1.DidAccountSizeHelper.fromAccount(didAccount.raw).getTotalNativeAccountSize()); if (didAccountSize < requiredSize) { this.resize(requiredSize, this._payer, this._resizeAuthority); } } }); } // Terminal Instructions instructions() { return __awaiter(this, void 0, void 0, function* () { // check if additional alloc instructions are needed. yield this.setAllocInstruction(); const instructionChain = []; if (this._initInstruction) { instructionChain.push(this._initInstruction); } if (this._resizeInstruction) { instructionChain.push(this._resizeInstruction); } instructionChain.push(...this._generalInstructions); if (this._closeInstruction) { instructionChain.push(this._closeInstruction); } // ethSign const finalInstructions = yield this.ethSignInstructions(instructionChain); // needs to be the last method. this.clearInstructions(); return finalInstructions; }); } transaction() { return __awaiter(this, void 0, void 0, function* () { const tx = new web3_js_1.Transaction(); const instructions = yield this.instructions(); // console.log(JSON.stringify(instructions, null, 2)); tx.add(...instructions); return tx; }); } rpc(opts) { return __awaiter(this, void 0, void 0, function* () { const provider = new anchor_1.AnchorProvider(this._connection, this._wallet, this._confirmOptions); try { const tx = yield this.transaction(); return yield provider.sendAndConfirm(tx, this._partialSigners, opts); } catch (err) { throw (0, anchor_1.translateError)(err, this._idlErrors); } finally { this.clear(); } }); } } exports.DidSolTransactionBuilder = DidSolTransactionBuilder; //# sourceMappingURL=DidSolTransactionBuilder.js.map