UNPKG

@newcoin-foundation/newcoin-sdk

Version:
1,246 lines (1,043 loc) 42.5 kB
// EOS imports import { Api, JsonRpc, RpcError } from "eosjs"; import { Transaction, TransactResult } from "eosjs/dist/eosjs-api-interfaces"; import { JsSignatureProvider } from 'eosjs/dist/eosjs-jssig'; // development only import { PushTransactionArgs } from "eosjs/dist/eosjs-rpc-interfaces"; const ecc = require("eosjs-ecc-priveos"); // Extra backend services import { JsonRpc as HJsonRpc } from "@eoscafe/hyperion"; // Newcoin services import { ActionGenerator as PoolsActionGenerator, RpcApi as PoolsRpcApi } from '@newcoin-foundation/newcoin.pools-js' import { PoolPayload as PoolsPayload } from '@newcoin-foundation/newcoin.pools-js/dist/interfaces/pool.interface'; import { ActionGenerator as MainDAOActionGenerator } from '@newcoin-foundation/newcoin.pool-js'; import { ActionGenerator as DaosAG, ChainApi as DaosChainApi } from '@newcoin-foundation/newcoin.daos-js' import { DAOPayload, GetTableRowsPayload, ProposalPayload } from "@newcoin-foundation/newcoin.daos-js/dist/interfaces"; import { ActionGenerator as sdkActionGen, EosioActionObject } from "./actions"; import fetch from 'cross-fetch'; import { NCKeyPair, NCCreateUser, NCCreateCollection, NCCreatePool, NCStakePool, NCUnstakePool, NCStakeMainDao, NCBuyRam, NCCreateDao, NCGetDaoWhiteList, NCCreateDaoProposal, NCCreateDaoUserWhitelistProposal, NCCreateDaoStakeProposal, NCApproveDaoProposal, NCExecuteDaoProposal, NCGetVotes, NCGetDaoProposals, NCDaoProposalVote, NCDaoWithdrawVoteDeposit, NCMintAsset, NCCreatePermission, NCGetAccInfo, NCGetPoolInfo, NCLinkPerm, NCPoolsInfo, NCNameType, NCReturnTxs, NCReturnInfo, NCTxBal, NCTxNcoBal, default_schema, SBT_NFT_schema } from "./types"; export { NCKeyPair, NCCreateUser, NCCreateCollection, NCCreatePool, NCStakePool, NCUnstakePool, NCStakeMainDao, NCCreateDao, NCGetDaoWhiteList, NCCreateDaoProposal, NCCreateDaoUserWhitelistProposal, NCCreateDaoStakeProposal, NCApproveDaoProposal, NCExecuteDaoProposal, NCGetVotes, NCGetDaoProposals, NCDaoProposalVote, NCMintAsset, NCCreatePermission, NCGetAccInfo, NCGetPoolInfo, NCLinkPerm, NCPoolsInfo, NCNameType, NCReturnTxs, NCReturnInfo, NCTxBal, NCTxNcoBal, default_schema }; import { normalizeUsername } from "./utils"; import { getClaimNftsActions, getClaimWinBidActions, getCreateAuctionActions, getEditAuctionActions, getEraseAuctionActions, getPlaceBidActions } from "./neftymarket"; import { NCClaimNftsParams, NCClaimWinBidParams, NCCreateAuctionParams, NCEditAuctionParams, NCEraseAuctionParams, NeftyMarketParamsBase, NCPlaceBidParams } from "./neftymarket/types"; const CREATE_ACCOUNT_DEFAULTS = { ram_amt: 8192, cpu_amount: '100.0000 NCO', net_amount: '100.0000 NCO', xfer: false, }; export type NCInitUrls = { nodeos_url: string, hyperion_url: string, atomicassets_url: string }; export type NCInitServices = { eosio_contract: string, token_contract: string, maindao_contract: string, staking_contract: string, daos_contract: string; neftymarket_contract: string; atomicassets_contract: string; }; export const devnet_urls: NCInitUrls = { nodeos_url: "https://nodeos-dev.newcoin.org", hyperion_url: "https://hyperion-dev.newcoin.org", atomicassets_url: "https://atomic-dev.newcoin.org/" }; export const devnet_services: NCInitServices = { eosio_contract: "eosio", token_contract: "eosio.token", maindao_contract: "pool.nco", staking_contract: "pools2.nco", daos_contract: "daos.nco", neftymarket_contract: "market.nefty", atomicassets_contract: "atomicassets" }; /** * The primary tool to interact with [https://newcoin.org](newcoin.org). * * This is an early alpha. * * See [https://docs.newcoin.org/](https://docs.newcoin.org/) for an overview of the newcoin ecosystem. */ export class NCO_BlockchainAPI { private urls: NCInitUrls; private services: NCInitServices; //private aa_api: ExplorerApi; private nodeos_rpc: JsonRpc; private hrpc: HJsonRpc; private poolsRpcApi: PoolsRpcApi; // private poolRpcApi: PoolRpcApi; private cApi: DaosChainApi; private aGen: DaosAG; private mGen: MainDAOActionGenerator; private pGen: PoolsActionGenerator; private sdkGen: sdkActionGen; private debug: boolean = false; static defaults = { devnet_services, devnet_urls, default_schema } /** * Init the api * @name newcoin-api * @param urls * @param services * @returns a Newcoin API instance */ constructor( urls: NCInitUrls, services: NCInitServices, debug: boolean = false ) { this.debug = debug; this.urls = urls; if(this.debug) console.log("Init URLS " + JSON.stringify(urls)); //this.aa_api = new ExplorerApi(this.urls.atomicassets_url, "atomicassets", { fetch: node_fetch }); this.nodeos_rpc = new JsonRpc(this.urls.nodeos_url, { fetch }); this.hrpc = new HJsonRpc(this.urls.hyperion_url, { fetch } as any); this.cApi = new DaosChainApi(this.urls.nodeos_url, services.daos_contract, fetch); this.poolsRpcApi = new PoolsRpcApi(this.urls.nodeos_url, services.staking_contract, fetch); // this.poolRpcApi = new PoolRpcApi(this.urls.nodeos_url, services.maindao_contract, fetch) this.aGen = new DaosAG(services.daos_contract, services.staking_contract); this.mGen = new MainDAOActionGenerator(services.maindao_contract, services.token_contract); this.pGen = new PoolsActionGenerator(services.staking_contract, services.maindao_contract); this.sdkGen = new sdkActionGen(services.eosio_contract, services.token_contract); this.services = services; } // Native EOS services /** * Create a key pair assuming a secure environment (not frontend) * @params none * @returns An EOS key pair */ async createKeyPair() { await ecc.initialize(); let opts = { secureEnv: true }; let p = await ecc.randomKey(0, opts); //let x = ecc.isValidPrivate(p); let t: NCKeyPair = { prv_key: p, pub_key: ecc.privateToPublic(p) }; return t as NCKeyPair; } /** * Create a user - multistage operation creating new user account, * defailt collection, schema and template for the account * @param NCCreateUser * @returns NCReturnTxs */ async createUser(inpt: NCCreateUser) { const { newUser, newacc_pub_active_key, newacc_pub_owner_key, payer, payer_prv_key, ram_amt, net_amount, cpu_amount, xfer } = { ...CREATE_ACCOUNT_DEFAULTS, ...inpt }; let res: NCReturnTxs = {}; let newacc_action = this.sdkGen.newaccount(newUser, payer, newacc_pub_active_key, newacc_pub_owner_key); let buyram_action = this.sdkGen.buyrambytes(newUser, payer, ram_amt); let delegatebw_action = this.sdkGen.delegateBw(newUser, payer, net_amount, cpu_amount, xfer); if(this.debug) console.log("before create account transaction"); const tres = await this.SubmitTx( [newacc_action, buyram_action, delegatebw_action], [ecc.privateToPublic(payer_prv_key)], [payer_prv_key] ) as TransactResult;// [] contained res.TxID_createAcc = tres.transaction_id; if(this.debug) console.log("createuser transaction complete"); return res; } async buyRam(inpt: NCBuyRam) { let buyram_action = this.sdkGen.buyrambytes(inpt.user, inpt.payer, inpt.ram_amt); const tres = await this.SubmitTx( [buyram_action], [ecc.privateToPublic(inpt.payer_prv_key)], [inpt.payer_prv_key] ) as TransactResult;// [] contained return { TxID_createAcc: tres.transaction_id } as NCReturnTxs; } /** * Create default collection for the account * @param NCCreateCollection * @returns Create Collection and template transactions' ids */ async createCollection(inpt: NCCreateCollection) { let t: any; let res: NCReturnTxs = {}; let tres: TransactResult; if (inpt.collection_name == undefined) inpt.collection_name = normalizeUsername(inpt.user, "z"); if (inpt.schema_name == undefined) inpt.schema_name = normalizeUsername(inpt.user, "w"); let sbt_sch_name = normalizeUsername(inpt.user, "s"); let user_public_active_key = ecc.privateToPublic(inpt.user_prv_active_key); let mkt_fee = inpt.mkt_fee ? inpt.mkt_fee : 0.05; let allow_notify = inpt.allow_notify ? inpt.allow_notify : true; t = this.sdkGen.createCollection( inpt.user, inpt.collection_name, [inpt.user], [inpt.user], mkt_fee, allow_notify ); if(this.debug) console.log(t); if(this.debug) console.log("createcol transaction"); tres = await this.SubmitTx([t], [user_public_active_key], [inpt.user_prv_active_key] ) as TransactResult; res.TxID_createCol = tres.transaction_id; if(this.debug) console.log(tres); if(this.debug) console.log("creating default schema "); let schema_fields = inpt.schema_fields ? inpt.schema_fields : default_schema; t = this.sdkGen.createSchema( inpt.user, inpt.collection_name, inpt.schema_name, schema_fields); if(this.debug) console.log(t); if(this.debug) console.log("createsch transaction"); tres = await this.SubmitTx([t], [user_public_active_key], [inpt.user_prv_active_key] ) as TransactResult; res.TxID_createSch = tres.transaction_id; if(this.debug) console.log(tres); if(this.debug) console.log("creating SBT schema"); let t1 = this.sdkGen.createSchema( inpt.user, inpt.collection_name, sbt_sch_name, SBT_NFT_schema); if(this.debug) console.log(t1); if(this.debug) console.log("createsch SBT transaction"); tres = await this.SubmitTx([t1], [user_public_active_key], [inpt.user_prv_active_key] ) as TransactResult; res.TxID_createSch = tres.transaction_id; if(this.debug) console.log(tres); if(this.debug) console.log("creating template"); let template = inpt.template_fields ? inpt.template_fields : []; let xferable = inpt.xferable ? inpt.xferable : true; let burnable = inpt.burnable ? inpt.burnable : true; t = this.sdkGen.createTemplate(inpt.user, inpt.collection_name, inpt.schema_name, xferable, burnable, template); if(this.debug) console.log(t); if(this.debug) console.log("creating template transaction"); tres = await this.SubmitTx([t], [user_public_active_key], [inpt.user_prv_active_key] ) as TransactResult; res.TxID_createTpl = res.TxID_createTpl; if(this.debug) console.log(tres); return res; } /** * Create a new permission subordinate to the Active permission. * (future optional: allow under owner, TBD) * @param NCCreatePermission * @returns Create permission transaction id */ async createPermission(inpt: NCCreatePermission) { let t = this.sdkGen.createPermission(inpt.author, inpt.perm_name, inpt.perm_pub_key); let res = await this.SubmitTx([t], [ecc.privateToPublic(inpt.author_prv_active_key)],[inpt.author_prv_active_key] ) as TransactResult; let r: NCReturnTxs = {}; r.TxID_createPerm = res.transaction_id; return r; } /** * Link a permission to a specific action of a specific contract. * @param NCLinkPerm * author: the permission's owner to be linked * code: the owner of the action to be linked * type: the action to be linked * 'active', 'owner' ... * @returns Link permission transaction id */ async linkPermission(inpt: NCLinkPerm) { const linkauth_input = { account: inpt.author, // this link code: inpt.action_owner, // type: inpt.action_to_link, // requirement: inpt.perm_to_link, // }; // the action which will make the linking let action = { account: 'eosio', name: 'linkauth', data: linkauth_input, authorization: [{ actor: inpt.author, permission: 'active' }] }; let res = await this.SubmitTx([action], [ecc.privateToPublic(inpt.author_prv_active_key)], [inpt.author_prv_active_key] ) as TransactResult; let r: NCReturnTxs = {}; r.TxID_linkPerm = res.transaction_id; return r; } /* ===================================================================================== * Main DAO service: common staking pool transfrming NCO (external convertible currency) * into internal GNCO currency. * * Staked amount is subject to a staking fee, redemption delay and/or * instant unstaking fee. * @param NCStakeMainDao * @returns NCReturnTxs */ async stakeMainDAO(inpt: NCStakeMainDao) { let r: NCReturnTxs = {}; const stakeTx = await this.mGen.stake( [{ actor: inpt.payer, permission: "active" }], inpt.payer, inpt.amt); if(this.debug) console.log("action: " + JSON.stringify(stakeTx)); const res = await this.SubmitTx(stakeTx, [ecc.privateToPublic(inpt.payer_prv_key)], [inpt.payer_prv_key]) as TransactResult; r.TxID_stakeMainDAO = res.transaction_id; return r; } /** * Instant UnStake mainDAO with penalty * @param NCStakeMainDao * @returns NCReturnTxs */ async instUnstakeMainDAO(inpt: NCStakeMainDao) { let r: NCReturnTxs = {}; const stakeTx = await this.mGen.instunstake( [{ actor: inpt.payer, permission: "active" }], inpt.payer, inpt.amt); if(this.debug) console.log("action: " + JSON.stringify(stakeTx)); const res = await this.SubmitTx(stakeTx, [ecc.privateToPublic(inpt.payer_prv_key)], [inpt.payer_prv_key]) as TransactResult; r.TxID_unstakeMainDAO = res.transaction_id; return r; } /** * Delayed UnStake mainDAO delay without penalty * @param NCStakeMainDao * @returns NCReturnTxs */ async dldUnstakeMainDAO(inpt: NCStakeMainDao) { let r: NCReturnTxs = {}; const stakeTx = await this.mGen.dldunstake( [{ actor: inpt.payer, permission: "active" }], inpt.payer, inpt.amt); if(this.debug) console.log("action: " + JSON.stringify(stakeTx)); const res = await this.SubmitTx(stakeTx, [ecc.privateToPublic(inpt.payer_prv_key)], [inpt.payer_prv_key]) as TransactResult; r.TxID_unstakeMainDAO = res.transaction_id; return r; } // ======================================================================== /** Staking pools service, issuing social tokens * * Create a staking pool for an account. * Selection of ticker and inflation/deflation optionality * @param NCCreatePool * @returns Create Pool transaction id */ async createPool(inpt: NCCreatePool) { inpt.ticker = (inpt.ticker || inpt.owner.substring(0, 5)).toUpperCase(); inpt.is_inflatable ??= true; inpt.is_deflatable ??= true; inpt.is_treasury ??= false; if(this.debug) console.log("Creating pool: " + JSON.stringify(inpt)); let t = this.sdkGen.createPool( inpt.owner, inpt.ticker, inpt.is_inflatable, inpt.is_deflatable, inpt.is_treasury, "test pool for " + inpt.owner ); let res = await this.SubmitTx([t], [ecc.privateToPublic(inpt.owner_prv_active_key)], [inpt.owner_prv_active_key] ) as TransactResult; let r: NCReturnTxs = {}; r.TxID_createPool = res.transaction_id; return r; } /** * Stake to creator pool * @param * @returns Create Pool transaction id */ async stakePool(inpt: NCStakePool) { let p: PoolsPayload = { owner: inpt.owner }; let r: NCReturnTxs = {}; type RetT = { rows: PoolsPayload[] }; if(this.debug) console.log("Get poolbyowner: ", JSON.stringify(p)); let q = await this.poolsRpcApi.getPoolByOwner(p); let t = await q.json() as RetT; const pool_id = t.rows[0].id as string; const pool_code = t.rows[0].code as string; if(this.debug) console.log("pool:" + JSON.stringify(t)); const stakeTx = await this.pGen.stakeToPool( [{ actor: inpt.payer, permission: "active" }], inpt.payer, inpt.amt, pool_id); if(this.debug) console.log("action: " + JSON.stringify(stakeTx)); const res = await this.SubmitTx(stakeTx, [ecc.privateToPublic(inpt.payer_prv_key)], [inpt.payer_prv_key]) as TransactResult; r.TxID_stakePool = res.transaction_id; r.pool_id = pool_id; r.pool_code = pool_code; return r; } // DAO functionality /** * Unstake creator pool * @param NCUnstakePool * @returns Create Pool transaction id */ async unstakePool(inpt: NCUnstakePool) { const t = await this.pGen.withdrawFromPool( [{ actor: inpt.payer, permission: "active" }], //{ actor: "io", permission: "active"} inpt.payer, inpt.amt); if(this.debug) console.log("action: " + JSON.stringify(t)); const res = await this.SubmitTx(t, [ecc.privateToPublic(inpt.payer_prv_key)], [inpt.payer_prv_key]) as TransactResult; let r: NCReturnTxs = {}; r.TxID_unstakePool = res.transaction_id; return r; } /** * DAO creation. One per account. * @param inpt : NCCreateDao * @returns NCReturnTxs.TxID_createDao, NCReturnTxs.dao_id */ async createDao(inpt: NCCreateDao) { const t = await this.aGen.createDao( [{ actor: inpt.author, permission: "active" }], inpt.author, inpt.descr ); const res = await this.SubmitTx(t, [ecc.privateToPublic(inpt.author_prv_key)], [inpt.author_prv_key]) as TransactResult; let p: DAOPayload = { owner: inpt.author }; if(this.debug) console.log("Get dao by owner: ", JSON.stringify(p)); let q = await this.cApi.getDAOByOwner(p); let w = await q.json(); if(this.debug) console.log("received from getDaoByOwner" + JSON.stringify(w)); let r: NCReturnTxs = {}; r.TxID_createDao = res.transaction_id; r.dao_id = w.rows[0].id.toString(); // r.dao_id = r.dao_id.toString() ; return r; } /** * * @param inpt : NCCreateDaoProposal * @returns NCReturnTxs.TxID_createDaoProposal, NCReturnTxs.proposal_id */ async createDaoProposal(inpt: NCCreateDaoProposal) { const dao_id = inpt.dao_id || (await this.getDaoIdByOwner(inpt.dao_owner)); const t = await this.aGen.createProposal( [{ actor: inpt.proposer, permission: "active" }], inpt.proposer, Number(dao_id), inpt.title, inpt.summary, inpt.url, inpt.vote_start, inpt.vote_end ); const res = await this.SubmitTx(t, [ecc.privateToPublic(inpt.proposer_prv_key)], [inpt.proposer_prv_key]) as TransactResult; let r: NCReturnTxs = {}; r.TxID_createDaoProposal = res.transaction_id; r.dao_id = dao_id; const ps = await this.getDaoProposals({...inpt, dao_id }); // r.dao_id, inpt.proposer r.proposal_id = ps.rows[ps.rows.length-1].id; return r; } /** * * @param inpt : NCCreateDaoUserWhitelistProposal * @returns NCReturnTxs.TxID_createDaoProposal, NCReturnTxs.proposal_id */ async createDaoUserWhitelistProposal(inpt: NCCreateDaoUserWhitelistProposal) { const dao_id = inpt.dao_id || (await this.getDaoIdByOwner(inpt.dao_owner)); const t = await this.aGen.createWhiteListProposal( [{ actor: inpt.proposer, permission: "active" }], inpt.proposer, Number(dao_id), inpt.user, inpt.vote_start, inpt.vote_end ); const res = await this.SubmitTx(t, [ecc.privateToPublic(inpt.proposer_prv_key)], [inpt.proposer_prv_key]) as TransactResult; let r: NCReturnTxs = {}; r.TxID_createDaoProposal = res.transaction_id; r.dao_id = dao_id; let ps = await this.getDaoWhitelistProposals( { dao_id: dao_id, proposal_author: inpt.proposer } as NCGetDaoProposals ); r.proposal_id = ps.rows[ps.rows.length - 1].id; return r; } /** * * @param inpt : NCCreateDaoUserWhitelistProposal * @returns NCReturnTxs.TxID_createDaoProposal, NCReturnTxs.proposal_id */ async createDaoStakeProposal(inpt: NCCreateDaoStakeProposal) { const dao_id = inpt.dao_id || (await this.getDaoIdByOwner(inpt.dao_owner)); const t = await this.aGen.createStakeProposal( [{ actor: inpt.proposer, permission: "active" }], inpt.proposer, Number(dao_id), inpt.to, inpt.quantity, inpt.vote_start, inpt.vote_end ); const res = await this.SubmitTx(t, [ecc.privateToPublic(inpt.proposer_prv_key)], [inpt.proposer_prv_key]) as TransactResult; let r: NCReturnTxs = {}; r.TxID_createDaoProposal = res.transaction_id; r.dao_id = dao_id; let ps = await this.getDaoStakeProposals( { dao_id: dao_id, proposal_author: inpt.proposer } as NCGetDaoProposals ); r.proposal_id = ps.rows[ps.rows.length - 1].id; return r; } /** * * @param inpt : NCApproveDaoProposal * @returns NCReturnTxs.TxID_approveDaoProposal */ async approveDaoProposal(inpt: NCApproveDaoProposal) { const dao_id = inpt.dao_id || (await this.getDaoIdByOwner(inpt.dao_owner)); if (inpt.proposal_id == undefined) throw ("Proposal undefined ID"); const t = await this.aGen.approveProposal( [{ actor: inpt.approver, permission: "active" }], Number(dao_id), inpt.proposal_id ); const res = await this.SubmitTx(t, [ecc.privateToPublic(inpt.approver_prv_key)], [inpt.approver_prv_key]) as TransactResult; let r: NCReturnTxs = {}; r.TxID_approveDaoProposal = res.transaction_id; return r; } /** * * @param inpt : NCApproveDaoProposal * @returns NCReturnTxs.TxID_approveDaoProposal */ async approveDaoWhitelistProposal(inpt: NCApproveDaoProposal) { const dao_id = inpt.dao_id || (await this.getDaoIdByOwner(inpt.dao_owner)); if (inpt.proposal_id == undefined) throw ("Proposal undefined ID"); const t = await this.aGen.approveWhiteListProposal( [{ actor: inpt.approver, permission: "active" }], Number(dao_id), inpt.proposal_id ); const res = await this.SubmitTx(t, [ecc.privateToPublic(inpt.approver_prv_key)], [inpt.approver_prv_key]) as TransactResult; let r: NCReturnTxs = {}; r.TxID_approveDaoProposal = res.transaction_id; return r; } /** * * @param inpt : NCExecuteDaoProposal * @returns NCReturnTxs.TxID_executeDaoProposal */ async executeDaoProposal(inpt: NCExecuteDaoProposal) { const dao_id = inpt.dao_id || (await this.getDaoIdByOwner(inpt.dao_owner)); if (inpt.proposal_id == undefined) throw ("Proposal ID undefined"); const t = await this.aGen.executeProposal( [{ actor: inpt.exec, permission: "active" }], Number(dao_id), inpt.proposal_id ); const res = await this.SubmitTx(t, [ecc.privateToPublic(inpt.exec_prv_key)], [inpt.exec_prv_key]) as TransactResult; let r: NCReturnTxs = {}; r.TxID_executeDaoProposal = res.transaction_id; return r; } /** * @param inpt : NCExecuteDaoProposal * @returns NCReturnTxs.TxID_executeDaoProposal */ async executeDaoWhitelistProposal(inpt: NCExecuteDaoProposal) { const dao_id = inpt.dao_id || (await this.getDaoIdByOwner(inpt.dao_owner)); if (inpt.proposal_id == undefined) throw ("Proposal ID undefined"); const t = await this.aGen.executeWhiteListProposal( [{ actor: inpt.exec, permission: "active" }], Number(dao_id), inpt.proposal_id ); const res = await this.SubmitTx(t, [ecc.privateToPublic(inpt.exec_prv_key)], [inpt.exec_prv_key]) as TransactResult; let r: NCReturnTxs = {}; r.TxID_executeDaoProposal = res.transaction_id; return r; } /** * @param inpt : NCCreateDao * @returns NCReturnTxs.TxID_createDao, NCReturnTxs.dao_id */ async voteOnProposal(inpt: NCDaoProposalVote) { const dao_id = inpt.dao_id || (await this.getDaoIdByOwner(inpt.dao_owner)); //if(this.debug) console.log("Vote for DAO proposal", JSON.stringify(inpt)); const t = await this.aGen.vote( [{ actor: inpt.voter, permission: "active" }], inpt.voter, inpt.quantity, inpt.proposal_type || "standart", dao_id, inpt.proposal_id, inpt.option ); if(this.debug) console.log("Vote for DAO proposal: ", JSON.stringify(t)); const res = await this.SubmitTx(t, [ecc.privateToPublic(inpt.voter_prv_key)], [inpt.voter_prv_key]) as TransactResult; //if(this.debug) console.log("received from VoteForDaoProposal" + JSON.stringify(res)); return { TxID_voteDaoProposal: res.transaction_id } as NCReturnTxs; } async withdrawVoteDeposit(inpt: NCDaoWithdrawVoteDeposit) { //const dao_id = inpt.dao_id || (await this.getDaoIdByOwner(inpt.dao_owner)); if(this.debug) console.log("withdraw vote deposit make action", JSON.stringify(inpt)); const t = await this.aGen.withdraw( [{ actor: inpt.voter, permission: "active" }], inpt.voter, +inpt.vote_id ); if(this.debug) console.log("Withdraw vote deposit send action: ", JSON.stringify(t)); const res = await this.SubmitTx(t, [ecc.privateToPublic(inpt.voter_prv_key)], [inpt.voter_prv_key]) as TransactResult; //if(this.debug) console.log("received from withdraw: " + JSON.stringify(res)); return { TxID_WithdrawVoteDeposit: res.transaction_id } as NCReturnTxs; } /** * Mint an asset * @param inpt: NCMintAsset * @returns Create Pool transaction id */ async mintAsset(inpt: NCMintAsset) { if (inpt.col_name == undefined) inpt.col_name = normalizeUsername(inpt.creator, "z"); if (inpt.sch_name == undefined) inpt.sch_name = normalizeUsername(inpt.creator, "w"); if (inpt.tmpl_id == undefined) inpt.tmpl_id = -1; if (inpt.immutable_data == undefined) inpt.immutable_data = [ { key: 'name', value: ['string', inpt.creator + '_' + (new Date()).getTime()] } ]; if (inpt.mutable_data == undefined) inpt.mutable_data = []; const t = this.sdkGen.mintAsset( inpt.creator, inpt.col_name, inpt.sch_name, inpt.tmpl_id, inpt.immutable_data, inpt.mutable_data ); let res = await this.SubmitTx([t], [ecc.privateToPublic(inpt.payer_prv_key)], [inpt.payer_prv_key] ) as TransactResult; let r: NCReturnTxs = {}; r.TxID_mintAsset = res.transaction_id; return r; } // Getters /** * @param inpt : NCCreateDao * @returns NCReturnTxs.TxID_createDao, NCReturnTxs.dao_id */ async getDaoIdByOwner(owner?: string, noFail?: boolean) : Promise<string> { if (!owner) throw new Error("DAO undefined"); let p: DAOPayload = { owner: owner } if(this.debug) console.log("Get dao by owner: ", JSON.stringify(p)); let q = await this.cApi.getDAOByOwner(p); let w = await q.json(); if(this.debug) console.log("received from getDaoByOwner" + JSON.stringify(w)); if (!w.rows.length && !noFail) throw new Error('User has no dao'); const r: string = w.rows[0]?.id?.toString(); if(!r && !noFail) throw new Error("DAO undefined"); return r; } async getDaoProposals(inpt: NCGetDaoProposals) { if(this.debug) console.log("Get proposal list: ", JSON.stringify(inpt)); const dao_id = inpt.dao_id || (await this.getDaoIdByOwner(inpt.dao_owner, true)); if(!dao_id) return { dao_id: null }; let w; if(inpt.proposal_author || inpt.proposal_id) { w = await (await this.cApi.getProposalByProposer({ ...inpt, daoID: dao_id })).json(); } else { const opt = { json: true, code: "daos.nco", scope: dao_id, table: "proposals", lower_bound: inpt.lower_bound, upper_bound: inpt.upper_bound, limit: ~~(inpt.limit??"10"), reverse: inpt.reverse, index_position: "1", } as GetTableRowsPayload; w = await (await this.cApi.getTableRows( opt )).json(); } if(this.debug) console.log("received proposal list" + JSON.stringify(w)); return { ...w, dao_id }; } async getDaoWhitelistProposals(inpt: NCGetDaoProposals) { if(this.debug) console.log("Get proposal list: ", JSON.stringify(inpt)); const dao_id = inpt.dao_id || (await this.getDaoIdByOwner(inpt.dao_owner, true)); if(!dao_id) return { dao_id: null }; let w; if(inpt.proposal_author || inpt.proposal_id) { w = await (await this.cApi.getWhiteListProposalByProposer({ ...inpt, daoID: dao_id })).json(); } else { const opt = { json: true, code: "daos.nco", scope: dao_id, table: "whlistprpls", lower_bound: inpt.lower_bound, upper_bound: inpt.upper_bound, limit: ~~(inpt.limit??"10"), reverse: inpt.reverse, index_position: "1", } as GetTableRowsPayload; w = await (await this.cApi.getTableRows( opt )).json(); } if(this.debug) console.log("received proposal list" + JSON.stringify(w)); return { ...w, dao_id }; } async getDaoStakeProposals(inpt: NCGetDaoProposals) { if(this.debug) console.log("Get proposal list: ", JSON.stringify(inpt)); const dao_id = inpt.dao_id || (await this.getDaoIdByOwner(inpt.dao_owner, true)); if(!dao_id) return { dao_id: null }; let w; if(inpt.proposal_author || inpt.proposal_id) { w = await (await this.cApi.getStakeProposalByProposer({ ...inpt, daoID: dao_id })).json(); } else { const opt = { json: true, code: "daos.nco", scope: dao_id, table: "stakeprpls", lower_bound: inpt.lower_bound, upper_bound: inpt.upper_bound, limit: ~~(inpt.limit??"10"), reverse: inpt.reverse, index_position: "1", } as GetTableRowsPayload; w = await (await this.cApi.getTableRows( opt )).json(); } if(this.debug) console.log("received proposal list" + JSON.stringify(w)); return { ...w, dao_id }; } async getDaoProposal(inpt: NCGetDaoProposals) { const dao_id = inpt.dao_id || (await this.getDaoIdByOwner(inpt.dao_owner)); if(!inpt.proposal_id) throw "Must provide proposal ID"; let w = await (await this.cApi.getProposalByID({ daoID: inpt.dao_id as string, id: inpt.proposal_id })).json(); if(this.debug) console.log("received from getProposalByID " + JSON.stringify(w.rows[0])); return { ...w, dao_id }; } async getDaoWhitelistProposal(inpt: NCGetDaoProposals) { const dao_id = inpt.dao_id || (await this.getDaoIdByOwner(inpt.dao_owner)); if (!inpt.proposal_id) throw "Must provide proposal ID"; let w = await (await this.cApi.getWhiteListProposal({ daoID: dao_id, id: inpt.proposal_id })).json(); if(this.debug) console.log("received from getProposalByID" + JSON.stringify(w.rows[0])); return { ...w, dao_id: inpt.dao_id }; } async listDaoProposals(inpt: NCGetDaoProposals) { const dao_id = inpt.dao_id || (await this.getDaoIdByOwner(inpt.dao_owner)); let opt: ProposalPayload = { daoID: dao_id}; //opt.proposer = inpt.proposal_author ?? undefined; if(this.debug) console.log("sent to getProposalByProposer: " + JSON.stringify(opt)); let q = await this.cApi.getProposalByProposer(opt); if(this.debug) console.log("received from getProposalByProposer: " + JSON.stringify(q)); let w = (await q.json()).rows; return { list: w, id: dao_id }; } async listDaoWhitelistProposals(inpt: NCGetDaoProposals) { const dao_id = inpt.dao_id || (await this.getDaoIdByOwner(inpt.dao_owner)); let opt: ProposalPayload = { daoID: dao_id}; //opt.proposer = inpt.proposal_author ?? undefined; let q = await this.cApi.getWhiteListProposalByProposer(opt); if(this.debug) console.log("received from getProposalByProposer: " + JSON.stringify(q)); let w = (await q.json()).rows; if(this.debug) console.log("received from getProposalByProposer: " + JSON.stringify(w)); return { list: w, id: dao_id }; } async getDaoWhitelist(inpt: NCGetDaoWhiteList) { const dao_id = inpt.dao_id || (await this.getDaoIdByOwner(inpt.dao_owner)); //let q = await this.cApi.getDAOWhiteList({ id: inpt.dao_id as string }); //let w = await q.json(); const opt = { json: true, code: "daos.nco", scope: dao_id, table: "whitelist", key_type: "name", lower_bound: inpt.lower_bound, upper_bound: inpt.upper_bound, limit: ~~(inpt.limit??"10"), reverse: inpt.reverse, index_position: "1", } as GetTableRowsPayload; let w = await (await this.cApi.getTableRows( opt )).json(); if(this.debug) console.log("received white list" + JSON.stringify(w)); return { ...w, dao_id }; } async getVotes(inpt: NCGetVotes) { let w; const opt = { json: true, code: "daos.nco", scope: inpt.voter, table: "votes", key_type: "i64", lower_bound: inpt.lower_bound, upper_bound: inpt.upper_bound, limit: ~~(inpt.limit??"10"), reverse: inpt.reverse, index_position: "1", } as GetTableRowsPayload; w = await (await this.cApi.getTableRows(opt)).json(); if(this.debug) console.log("received from getVotes " + JSON.stringify(w.rows)); return w; } /** * Get account balance * @param acc: NCGetAccInfo * @param acc.token_name will set correct contract * @returns Tx data */ async getAccountBalance(acc: NCGetAccInfo) { if (!acc.contract) { if (acc.token_name == "GNCO") acc.contract = this.services.maindao_contract; else if (acc.token_name != "NCO") acc.contract = this.services.staking_contract; else acc.contract = this.services.eosio_contract; } let rc: NCReturnInfo = { acc_balances: [] }; try { let t = await fetch(`https://nodeos-dev.newcoin.org/v1/chain/get_currency_balance`, { // TODO method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ account: acc.owner, code: acc.contract }), }); rc.acc_balances = await t.json(); //if(this.debug) if(this.debug) console.log(rc); return rc; } catch (e) { if(this.debug) console.log('\nCaught exception: ' + e); if (e instanceof RpcError && this.debug) console.log(JSON.stringify(e.json, null, 2)); throw e; } } /** * Transfer GNCO between accounts * @param NCTxBal * @returns Transfer transaction id */ async txGNCOBalance(inpt: NCTxBal) { const r = await this._txBalance(this.services.maindao_contract, inpt); return r; } /** * Transfer NCO between accounts * @param NCTxBal * @returns Transfer transaction id */ async txNCOBalance(inpt: NCTxBal) { const r = await this._txBalance(this.services.token_contract, inpt); return r; } /** * Transfer creator tokens between accounts * @param NCTxBal * @returns Transfer transaction id */ async txDAOTokenBalance(inpt: NCTxBal) { const r = await this._txBalance(this.services.staking_contract, inpt); return r; } /** * Get pool info * @param * @returns Tx data */ async getPoolInfo(payload: NCGetPoolInfo) { const api = new PoolsRpcApi("https://nodeos-dev.newcoin.org", "pools2.nco", fetch); // TODO try { const fn = payload.code ? "getPoolByCode" : "getPoolByOwner"; let q = await api[fn](payload); let t = await q.json() as NCPoolsInfo; return t; } catch (e) { if(this.debug) console.log('\nCaught exception: ' + e); if (e instanceof RpcError) if(this.debug) console.log(JSON.stringify(e.json, null, 2)); } return {} as NCPoolsInfo; `` } /** * Get trasaction data * @returns Tx data */ async getTxData(txid: string) { let txi = await this.hrpc.get_transaction(txid); if(this.debug) console.log(txi); // get template number txi.actions[1].act.data.template_id return txi; } // AUX functions /** * Transfer NCO between accounts * @returns Transfer transaction id */ async _txBalance(contract: string, inpt: NCTxBal): Promise<NCReturnTxs> { let r: NCReturnTxs = {}; let tx = this.sdkGen.txBalance(contract, inpt.payer, inpt.to, inpt.amt, inpt.memo ??= ""); let res = await this.SubmitTx([tx], [ecc.privateToPublic(inpt.payer_prv_key)], [inpt.payer_prv_key] ) as TransactResult; r.TxID = res.transaction_id; return r; } // Neftymarket private getActionParams<T>(params: T): NeftyMarketParamsBase & T { return { atomicassetsContract: this.services.atomicassets_contract, neftymarketContract: this.services.neftymarket_contract, ...params, }; } private async submitAuctionTx(actions: EosioActionObject[], payer_prv_key: string): Promise<NCReturnTxs> { const response = await this.SubmitTx( actions, [ecc.privateToPublic(payer_prv_key)], [payer_prv_key] ) as TransactResult; return { TxID: response.transaction_id, }; } // Nefty market actions /** * Create a new auction with the specified parameters * @returns create auction transaction id */ async createAuction(params: NCCreateAuctionParams, key: string) { const actions = getCreateAuctionActions(this.getActionParams(params)); return this.submitAuctionTx(actions, key); } /** * Place a new bid into an active auction * @returns bid transaction id */ async placeAuctionBid(params: NCPlaceBidParams, key: string) { const actions = getPlaceBidActions(this.getActionParams(params)); return this.submitAuctionTx(actions, key); } /** * Claim NFTs whenever you win an auction * @returns claim transaction id */ async claimNftsFromAuction(params: NCClaimNftsParams, key: string) { const actions = getClaimNftsActions(this.getActionParams(params)); return this.submitAuctionTx(actions, key); } /** * Claim the winning bid as the seller of an auction * @returns claim transaction id */ async claimAuctionWinBid(params: NCClaimWinBidParams, key: string) { const actions = getClaimWinBidActions(this.getActionParams(params)); return this.submitAuctionTx(actions, key); } /** * Erase an auction as long as it has no bids * @returns delete transaction id */ async eraseAuction(params: NCEraseAuctionParams, key: string) { const actions = getEraseAuctionActions(this.getActionParams(params)); return this.submitAuctionTx(actions, key); } /** * Edit an auction with the specified parameters, internally it erases the existing one * and creates a new one with the specified parameters. * @returns transaction id */ async editAuction(params: NCEditAuctionParams, key: string ) { const actions = getEditAuctionActions(this.getActionParams(params)); return this.submitAuctionTx(actions, key); } async SubmitTx( actions: any[], public_keys: string[], // testnet ["EOS5PU92CupzxWEuvTMcCNr3G69r4Vch3bmYDrczNSHx5LbNRY7NT"] private_keys: string[] // testnet ["5KdRwMUrkFssK2nUXASnhzjsN1rNNiy8bXAJoHYbBgJMLzjiXHV"] ) { const signatureProvider = new JsSignatureProvider(private_keys); signatureProvider.availableKeys = public_keys; //@ts-ignore const rpc = this.nodeos_rpc; const api = new Api({ rpc, signatureProvider }); //required to submit transactions const info = await rpc.get_info(); const lastBlockInfo = await rpc.get_block(info.last_irreversible_block_num) const tzOff = new Date(info.head_block_time).getTimezoneOffset(); var t = new Date((new Date(info.head_block_time)).getTime() + 10 * 60 * 1000 - tzOff * 1000 * 60).toISOString().slice(0, -1);//+10m const transactionObj: Transaction = { actions: actions, expiration: t, ref_block_prefix: lastBlockInfo.ref_block_prefix, //info.last_irreversible_block_num ref_block_num: lastBlockInfo.block_num & 0xffff, // 22774 }; if (this.debug) console.log("actions before serialization: " + JSON.stringify(transactionObj.actions)); const a = await api.serializeActions(transactionObj.actions); const transaction = { ...transactionObj, actions: a }; const serializedTransaction = api.serializeTransaction(transaction); const availableKeys = await api.signatureProvider.getAvailableKeys(); const requiredKeys = await api.authorityProvider.getRequiredKeys({ transaction, availableKeys }); const abis = await api.getTransactionAbis(transaction); // const pushTransactionArgs: PushTransactionArgs = { serializedTransaction, signatures }; let tx = { chainId: info.chain_id, // from getinfo requiredKeys: requiredKeys, serializedTransaction: serializedTransaction, serializedContextFreeData: undefined, abis: abis }; const pushTransactionArgs: PushTransactionArgs = await api.signatureProvider.sign(tx); /* let tr = serializedTransaction.buffer.toString(); let eccst = ecc.sign(serializedTransaction, private_keys[0]); let pub_from_prv = ecc.privateToPublic(private_keys[0]); let sig = pushTransactionArgs.signatures[0]; let key = ecc.recover(sig, tr); let c = ecc.verify(sig, tr, public_keys[0]); console.log("signature verification: return %d", c)*/ return api.pushSignedTransaction(pushTransactionArgs); }; }