UNPKG

@kanalabs/paymaster-sdk

Version:
400 lines (399 loc) 20.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()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.PaymasterSdk = void 0; const ts_sdk_1 = require("@aptos-labs/ts-sdk"); const constants_1 = require("./constants"); const cross_fetch_1 = __importDefault(require("cross-fetch")); // PaymasterSdk class for interacting with the Kanalabs paymaster API. class PaymasterSdk { // PaymasterSdk constructor. // @param walletProvider - Wallet provider configuration. // @param optionsLike - SDK options. constructor(walletProvider, optionsLike) { var _a; // Base URL for Gas Service API this.baseUrl = constants_1.PAYMASTER_BASE_URL; if (optionsLike.network !== ts_sdk_1.Network.MAINNET && optionsLike.network !== ts_sdk_1.Network.TESTNET && optionsLike.network !== undefined) { throw new Error('Invalid network'); } const config = new ts_sdk_1.AptosConfig(Object.assign({ network: (_a = optionsLike.network) !== null && _a !== void 0 ? _a : ts_sdk_1.Network.MAINNET, fullnode: optionsLike.nodeUrl !== null ? optionsLike.nodeUrl : optionsLike.network === ts_sdk_1.Network.TESTNET ? constants_1.TESTNET_NODE_URL : constants_1.MAINNET_NODE_URL }, (optionsLike.aptosApiKey && { clientConfig: { API_KEY: optionsLike.aptosApiKey } }))); this.network = optionsLike.network; this.projectKey = optionsLike.projectKey; this.aptosClient = new ts_sdk_1.Aptos(config); this.wallet = walletProvider.privateKey ? ts_sdk_1.Account.fromPrivateKey({ privateKey: new ts_sdk_1.Ed25519PrivateKey(walletProvider.privateKey), }) : undefined; } /** * @deprecated This endpoint is deprecated because Aptos accounts do not need to be manually initialized anymore. * Initialize the user's account. * @returns Success and message information. */ initAccount(args) { var _a; return __awaiter(this, void 0, void 0, function* () { const address = (args === null || args === void 0 ? void 0 : args.address) ? args.address : this.wallet ? this.wallet.accountAddress.toString() : (() => { throw new Error('No address provided'); })(); const url = `${this.baseUrl}/initAccount`; const query = { address: address, coin: (_a = args === null || args === void 0 ? void 0 : args.coin) !== null && _a !== void 0 ? _a : '' }; const params = new URLSearchParams(query).toString(); const headers = this.getCommonHeaders(); try { const response = yield (0, cross_fetch_1.default)(`${url}?${params}`, { headers }); if (response.status >= 400) { yield response.json().then((data) => { throw new Error((data === null || data === void 0 ? void 0 : data.error) || (data === null || data === void 0 ? void 0 : data.message) || 'Error in initializing Aptos account for user.'); }); } return yield response.json(); } catch (error) { throw (error === null || error === void 0 ? void 0 : error.data) || (error === null || error === void 0 ? void 0 : error.message) || error; } }); } // Add the user to the whitelist. // @returns Success and message information. addToWhitelist(args) { return __awaiter(this, void 0, void 0, function* () { const url = `${this.baseUrl}/addToWhitelist`; const address = (args === null || args === void 0 ? void 0 : args.address) ? args.address : this.wallet ? this.wallet.accountAddress.toString() : (() => { throw new Error('No address provided'); })(); const query = { user_address: address }; const params = new URLSearchParams(query).toString(); const headers = this.getCommonHeaders(); try { const response = yield (0, cross_fetch_1.default)(`${url}?${params}`, { headers, method: 'GET' }); if (response.status >= 400) { yield response.json().then((data) => { throw new Error((data === null || data === void 0 ? void 0 : data.error) || (data === null || data === void 0 ? void 0 : data.message) || 'Error in adding user to whitelist.'); }); } return yield response.json(); } catch (error) { throw (error === null || error === void 0 ? void 0 : error.data) || error; } }); } // Disables user on the whitelist to stop sponsored txns. // @returns Success and message information. disableUser(args) { return __awaiter(this, void 0, void 0, function* () { const url = `${this.baseUrl}/modifyUserState`; const address = (args === null || args === void 0 ? void 0 : args.address) ? args.address : this.wallet ? this.wallet.accountAddress.toString() : (() => { throw new Error('No address provided'); })(); const query = { user_address: address, status: 'false' }; const params = new URLSearchParams(query).toString(); const headers = this.getCommonHeaders(); try { const response = yield (0, cross_fetch_1.default)(`${url}?${params}`, { headers, method: 'GET' }); if (response.status >= 400) { yield response.json().then((data) => { throw new Error((data === null || data === void 0 ? void 0 : data.error) || (data === null || data === void 0 ? void 0 : data.message) || 'Error in disabling user.'); }); } return yield response.json(); } catch (error) { throw (error === null || error === void 0 ? void 0 : error.data) || error; } }); } // Enables user on the whitelist to start sponsored txns. // @returns Success and message information. enableUser(args) { return __awaiter(this, void 0, void 0, function* () { const url = `${this.baseUrl}/modifyUserState`; const address = (args === null || args === void 0 ? void 0 : args.address) ? args.address : this.wallet ? this.wallet.accountAddress.toString() : (() => { throw new Error('No address provided'); })(); const query = { user_address: address, status: 'true' }; const params = new URLSearchParams(query).toString(); const headers = this.getCommonHeaders(); try { const response = yield (0, cross_fetch_1.default)(`${url}?${params}`, { headers, method: 'GET' }); if (response.status >= 400) { yield response.json().then((data) => { throw new Error((data === null || data === void 0 ? void 0 : data.error) || (data === null || data === void 0 ? void 0 : data.message) || 'Error in enabling user.'); }); } return yield response.json(); } catch (error) { throw (error === null || error === void 0 ? void 0 : error.data) || error; } }); } // Check if the user is whitelisted. // @returns Success and message information. isWhitelisted(args) { return __awaiter(this, void 0, void 0, function* () { const url = `${this.baseUrl}/isWhitelisted`; const address = (args === null || args === void 0 ? void 0 : args.address) ? args.address : this.wallet ? this.wallet.accountAddress.toString() : (() => { throw new Error('No address provided'); })(); const query = { address: address }; const params = new URLSearchParams(query).toString(); const headers = this.getCommonHeaders(); try { const response = yield (0, cross_fetch_1.default)(`${url}?${params}`, { headers, method: 'GET' }); if (response.status >= 400) { yield response.json().then((data) => { throw new Error((data === null || data === void 0 ? void 0 : data.error) || (data === null || data === void 0 ? void 0 : data.message) || 'Error in checking whitelist status.'); }); } return yield response.json(); } catch (error) { throw (error === null || error === void 0 ? void 0 : error.data) || error; } }); } // Perform a sponsored transaction. // @param payload - Transaction payload. // @returns Pending transaction information. sponsoredTxn(args) { var _a; return __awaiter(this, void 0, void 0, function* () { try { if (this.wallet === undefined) { throw new Error('No wallet'); } const transaction = yield this.aptosClient.transaction.build.simple({ sender: this.wallet.accountAddress.toString(), data: args.data, options: args.options, withFeePayer: true, }); const senderAuth = this.aptosClient.transaction.sign({ signer: this.wallet, transaction, }); const rawTransactionBytes = transaction.rawTransaction.bcsToBytes(); const url = `${this.baseUrl}/sponsorGas`; const headers = this.getCommonHeaders(); const response = yield (0, cross_fetch_1.default)(url, { method: 'POST', headers: headers, body: JSON.stringify({ data: rawTransactionBytes }), }); if (response.status >= 400) { yield response.json().then((data) => { throw new Error((data === null || data === void 0 ? void 0 : data.error) || (data === null || data === void 0 ? void 0 : data.message) || 'Error in sponsoring transaction.'); }); } const responseData = yield response.json(); const feePayerAddress = responseData.feePayerAddress; const feepayerSignature = new Uint8Array(Object.values(responseData.feePayerAuth)); const deserializerFeePayer = new ts_sdk_1.Deserializer(feepayerSignature); const feepayerAuth = ts_sdk_1.AccountAuthenticator.deserialize(deserializerFeePayer); const committedTxn = yield this.aptosClient.transaction.submit.simple({ transaction: { rawTransaction: transaction.rawTransaction, feePayerAddress: ts_sdk_1.AccountAddress.fromString(feePayerAddress), }, senderAuthenticator: senderAuth, feePayerAuthenticator: feepayerAuth, }); return committedTxn; } catch (error) { throw ((_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.data) || error; } }); } /// Perform a sponsored transaction with senderAuth and transaction bytes. /// @param transaction - Generated transaction. SimpleTransaction or MultiAgentTransaction. /// @param senderAuth - Sender authenticator. /// @param additionalAuthenticators - Additional signer authenticators. /// @param additionalAddresses - Secondary signer addresses. /// @returns Pending transaction information. sponsoredTxnWithSenderAuth(args) { var _a; return __awaiter(this, void 0, void 0, function* () { try { const { transaction, senderAuth, additionalAuthenticators, additionalAddresses } = args; const url = `${this.baseUrl}/sponsorGas`; const headers = this.getCommonHeaders(); const rawTransactionBytes = transaction.rawTransaction.bcsToBytes(); const requestBody = { data: rawTransactionBytes }; if (additionalAuthenticators && additionalAddresses) { if (additionalAuthenticators.length !== additionalAddresses.length) { throw new Error('No of Additional Authenticators and address length mismatch'); } requestBody.additionalSigners = additionalAddresses.map((address) => address.toString()); } const response = yield (0, cross_fetch_1.default)(url, { method: 'POST', headers: headers, body: JSON.stringify(requestBody), }); if (response.status >= 400) { yield response.json().then((data) => { throw new Error((data === null || data === void 0 ? void 0 : data.error) || (data === null || data === void 0 ? void 0 : data.message) || 'Error in sponsoring transaction.'); }); } const responseData = yield response.json(); const feePayerAddress = responseData.feePayerAddress; const feepayerSignature = new Uint8Array(Object.values(responseData.feePayerAuth)); if (additionalAuthenticators && additionalAddresses) { const deserializerFeePayer = new ts_sdk_1.Deserializer(feepayerSignature); const feepayerAuth = ts_sdk_1.AccountAuthenticator.deserialize(deserializerFeePayer); // For multi agent transaction return yield this.aptosClient.transaction.submit.multiAgent({ transaction: { rawTransaction: transaction.rawTransaction, feePayerAddress: ts_sdk_1.AccountAddress.fromString(feePayerAddress), secondarySignerAddresses: additionalAddresses, }, senderAuthenticator: senderAuth, feePayerAuthenticator: feepayerAuth, additionalSignersAuthenticators: additionalAuthenticators, }); } else { const deserializerFeePayer = new ts_sdk_1.Deserializer(feepayerSignature); const feepayerAuth = ts_sdk_1.AccountAuthenticator.deserialize(deserializerFeePayer); // For simple transaction return yield this.aptosClient.transaction.submit.simple({ transaction: { rawTransaction: transaction.rawTransaction, feePayerAddress: ts_sdk_1.AccountAddress.fromString(feePayerAddress), }, senderAuthenticator: senderAuth, feePayerAuthenticator: feepayerAuth, }); } } catch (error) { throw ((_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.data) || error; } }); } addWhitelistFunctions(args) { return __awaiter(this, void 0, void 0, function* () { const url = `${this.baseUrl}/addWhitelistFunctions`; const headers = this.getCommonHeaders(); try { // Send a POST request to the server with the functions data in the body const response = yield (0, cross_fetch_1.default)(url, { method: 'POST', headers: headers, body: JSON.stringify({ functions: args.functions, signature: args.signature, publicKey: args.publicKey }), }); if (response.status >= 400) { yield response.json().then((data) => { throw new Error((data === null || data === void 0 ? void 0 : data.error) || (data === null || data === void 0 ? void 0 : data.message) || 'Error in adding whitelist functions.'); }); } return yield response.json(); } catch (error) { throw (error === null || error === void 0 ? void 0 : error.data) || error; } }); } addModuleWhitelistFunctions(args) { return __awaiter(this, void 0, void 0, function* () { const url = `${this.baseUrl}/addModuleWhitelistFunctions`; const headers = this.getCommonHeaders(); try { // Send a POST request to the server with the functions data in the body const response = yield (0, cross_fetch_1.default)(url, { method: 'POST', headers: headers, body: JSON.stringify({ functions: args.functions, signature: args.signature, publicKey: args.publicKey }), }); if (response.status >= 400) { yield response.json().then((data) => { throw new Error((data === null || data === void 0 ? void 0 : data.error) || (data === null || data === void 0 ? void 0 : data.message) || 'Error in adding module whitelist functions.'); }); } return yield response.json(); } catch (error) { throw (error === null || error === void 0 ? void 0 : error.data) || error; } }); } getDappFeePayerAddress() { return __awaiter(this, void 0, void 0, function* () { const url = `${this.baseUrl}/getDappFeePayerAddress`; const headers = this.getCommonHeaders(); try { // Send a GET request with headers const response = yield (0, cross_fetch_1.default)(url, { method: 'GET', headers: headers, }); // Check for errors in the response if (response.status >= 400) { const data = yield response.json(); throw new Error((data === null || data === void 0 ? void 0 : data.error) || (data === null || data === void 0 ? void 0 : data.message) || 'Error fetching dApp Fee Payer Address.'); } // Return the parsed response JSON return yield response.json(); } catch (error) { // Re-throw the error with relevant details throw (error === null || error === void 0 ? void 0 : error.data) || error; } }); } // Get common headers for requests. // @returns Common headers. getCommonHeaders() { var _a, _b; return { 'Content-Type': 'application/json', 'api-key': this.projectKey, network: (_a = this.network) !== null && _a !== void 0 ? _a : ts_sdk_1.Network.MAINNET, chain: (_b = this.chain) !== null && _b !== void 0 ? _b : constants_1.chainName.Aptos, }; } } exports.PaymasterSdk = PaymasterSdk;