diff --git a/README.md b/README.md
index 96b56375..293fde6b 100644
--- a/README.md
+++ b/README.md
@@ -222,6 +222,11 @@ This is the expected Private Key:
This is the expected Public Key:
"FIO5kJKNHwctcfUM5XZyiWSqSTM5HTzznJP9F3ZdbhaQAHEVq575o"
+## Version 1.9.0
+### Breaking changes:
+- Set new parameter `authPermission` for sign and push transactions
+- `pushTransaction` receives object params instead of multiple arguments
+
## Version 1.0.2
Bug Fix to method: addPublicAddresses - TechnologyProviderId (i.e. TPID), was not being set correctly for this method.
diff --git a/documentation/classes/fiosdk.html b/documentation/classes/fiosdk.html
index 37214e0c..385ca18e 100644
--- a/documentation/classes/fiosdk.html
+++ b/documentation/classes/fiosdk.html
@@ -1063,13 +1063,13 @@
Returns Promise
pushTransaction
- - pushTransaction(account: string, action: string, data: any): Promise<any>
+ - pushTransaction({account: string, action: string, authPermission: string | undefined, data: any, encryptOptions: EncryptOptions, signingAccount: string | undefined}): Promise<any>
-
+ -
+
authPermission: string | undefined
+
+
-
data: any
+ -
+
encryptOptions: EncryptOptions
+
+
+ -
+
signingAccount: string | undefined
+
+
Returns Promise<any>
diff --git a/lib/FIOSDK.js b/lib/FIOSDK.js
index b828477f..38c261ab 100644
--- a/lib/FIOSDK.js
+++ b/lib/FIOSDK.js
@@ -949,11 +949,15 @@ class FIOSDK {
const { fee: stakeFee } = yield this.getFee(EndPoint_1.EndPoint.stakeFioTokens, fioAddress);
fee = stakeFee;
}
- return this.pushTransaction('fio.staking', 'stakefio', {
- amount,
- fio_address: fioAddress,
- max_fee: fee,
- tpid: technologyProviderId,
+ return this.pushTransaction({
+ account: 'fio.staking',
+ action: 'stakefio',
+ data: {
+ amount,
+ fio_address: fioAddress,
+ max_fee: fee,
+ tpid: technologyProviderId,
+ },
});
});
}
@@ -971,11 +975,15 @@ class FIOSDK {
const { fee: stakeFee } = yield this.getFee(EndPoint_1.EndPoint.unStakeFioTokens, fioAddress);
fee = stakeFee;
}
- return this.pushTransaction('fio.staking', 'unstakefio', {
- amount,
- fio_address: fioAddress,
- max_fee: fee,
- tpid: technologyProviderId,
+ return this.pushTransaction({
+ account: 'fio.staking',
+ action: 'unstakefio',
+ data: {
+ amount,
+ fio_address: fioAddress,
+ max_fee: fee,
+ tpid: technologyProviderId,
+ },
});
});
}
@@ -993,7 +1001,7 @@ class FIOSDK {
* @param data JSON object with params for action
* @param encryptOptions JSON object with params for encryption
*/
- pushTransaction(account, action, data, encryptOptions = {}) {
+ pushTransaction({ account, action, data, authPermission, encryptOptions = {}, signingAccount, }) {
return __awaiter(this, void 0, void 0, function* () {
data.tpid = this.getTechnologyProviderId(data.tpid);
if (data.content && !encryptOptions.key) {
@@ -1014,7 +1022,14 @@ class FIOSDK {
//
}
}
- const pushTransaction = new SignedTransactions.PushTransaction(action, account, data, encryptOptions);
+ const pushTransaction = new SignedTransactions.PushTransaction({
+ action,
+ account,
+ authPermission,
+ data,
+ encryptOptions,
+ signingAccount,
+ });
return pushTransaction.execute(this.privateKey, this.publicKey, this.returnPreparedTrx);
});
}
@@ -1161,7 +1176,14 @@ class FIOSDK {
case 'getMultiplier':
return this.getMultiplier();
case 'pushTransaction':
- return this.pushTransaction(params.account, params.action, params.data, params.encryptOptions);
+ return this.pushTransaction({
+ account: params.account,
+ action: params.action,
+ data: params.data,
+ authPermission: params.authPermission,
+ encryptOptions: params.encryptOptions,
+ signingAccount: params.signingAccount,
+ });
case 'getAccountPubKey':
return this.getAccountPubKey(params.account);
case 'getEncryptKey':
diff --git a/lib/transactions/Transactions.js b/lib/transactions/Transactions.js
index 6f1d49bd..7ada2c87 100644
--- a/lib/transactions/Transactions.js
+++ b/lib/transactions/Transactions.js
@@ -169,7 +169,7 @@ class Transactions {
textEncoder,
});
}
- createRawTransaction({ account, action, data, publicKey, chainData }) {
+ createRawTransaction({ account, action, authPermission, data, publicKey, chainData, signingAccount }) {
return __awaiter(this, void 0, void 0, function* () {
const rawTransaction = new RawTransaction_1.RawTransaction();
const rawaction = new RawAction_1.RawAction();
@@ -178,10 +178,11 @@ class Transactions {
if (!data.actor) {
data.actor = actor;
}
- rawaction.authorization.push(new Autorization_1.Autorization(data.actor, data.permission));
+ rawaction.authorization.push(new Autorization_1.Autorization(data.actor, authPermission));
rawaction.account = account;
rawaction.name = action;
rawaction.data = data;
+ rawaction.actor = signingAccount;
rawTransaction.actions.push(rawaction);
if (chainData && chainData.ref_block_num) {
this.setRawTransactionExp(rawTransaction, chainData);
diff --git a/lib/transactions/signed/PushTransaction.js b/lib/transactions/signed/PushTransaction.js
index c9826083..40fe93eb 100644
--- a/lib/transactions/signed/PushTransaction.js
+++ b/lib/transactions/signed/PushTransaction.js
@@ -4,7 +4,7 @@ exports.PushTransaction = void 0;
const constants_1 = require("../../utils/constants");
const SignedTransaction_1 = require("./SignedTransaction");
class PushTransaction extends SignedTransaction_1.SignedTransaction {
- constructor(action, account, data, encryptOptions = {}) {
+ constructor({ action, account, authPermission, data, encryptOptions = {}, signingAccount, }) {
super();
this.ENDPOINT = 'chain/push_transaction';
this.ACTION = '';
@@ -15,13 +15,15 @@ class PushTransaction extends SignedTransaction_1.SignedTransaction {
}
this.data = data;
this.encryptOptions = encryptOptions;
+ this.authPermission = authPermission;
+ this.signingAccount = signingAccount;
}
getData() {
const data = Object.assign({}, this.data);
if (data.content && this.encryptOptions && this.encryptOptions.key && this.encryptOptions.contentType) {
data.content = this.getCipherContent(this.encryptOptions.contentType, data.content, this.privateKey, this.encryptOptions.key);
}
- return Object.assign(Object.assign({}, data), { actor: this.data.actor != null && this.data.actor !== '' ? this.data.actor : this.getActor(), permission: this.data.permission || 'active' });
+ return Object.assign(Object.assign({}, data), { actor: this.data.actor != null && this.data.actor !== '' ? this.data.actor : this.getActor() });
}
}
exports.PushTransaction = PushTransaction;
diff --git a/lib/transactions/signed/SignedTransaction.js b/lib/transactions/signed/SignedTransaction.js
index b4a8cafd..c0baa7fb 100644
--- a/lib/transactions/signed/SignedTransaction.js
+++ b/lib/transactions/signed/SignedTransaction.js
@@ -38,7 +38,9 @@ class SignedTransaction extends Transactions_1.Transactions {
const rawTransaction = yield this.createRawTransaction({
account: this.getAccount(),
action: this.getAction(),
+ authPermission: this.getAuthPermission(),
data: this.getData(),
+ signingAccount: this.getSigningAccount(),
});
const result = yield this.pushToServer(rawTransaction, this.getEndPoint(), dryRun);
return this.prepareResponse(result);
@@ -53,6 +55,12 @@ class SignedTransaction extends Transactions_1.Transactions {
getAccount() {
return this.ACCOUNT;
}
+ getAuthPermission() {
+ return this.authPermission;
+ }
+ getSigningAccount() {
+ return this.signingAccount;
+ }
getEndPoint() {
return this.ENDPOINT;
}
diff --git a/src/FIOSDK.ts b/src/FIOSDK.ts
index af1373c2..8514fa55 100644
--- a/src/FIOSDK.ts
+++ b/src/FIOSDK.ts
@@ -1403,16 +1403,16 @@ export class FIOSDK {
const { fee: stakeFee } = await this.getFee(EndPoint.stakeFioTokens, fioAddress)
fee = stakeFee
}
- return this.pushTransaction(
- 'fio.staking',
- 'stakefio',
- {
+ return this.pushTransaction({
+ account: 'fio.staking',
+ action: 'stakefio',
+ data: {
amount,
fio_address: fioAddress,
max_fee: fee,
tpid: technologyProviderId,
},
- )
+ })
}
/**
@@ -1433,16 +1433,16 @@ export class FIOSDK {
const { fee: stakeFee } = await this.getFee(EndPoint.unStakeFioTokens, fioAddress)
fee = stakeFee
}
- return this.pushTransaction(
- 'fio.staking',
- 'unstakefio',
- {
+ return this.pushTransaction({
+ account: 'fio.staking',
+ action: 'unstakefio',
+ data: {
amount,
fio_address: fioAddress,
max_fee: fee,
tpid: technologyProviderId,
},
- )
+ })
}
/**
@@ -1460,12 +1460,21 @@ export class FIOSDK {
* @param data JSON object with params for action
* @param encryptOptions JSON object with params for encryption
*/
- public async pushTransaction(
+ public async pushTransaction({
+ account,
+ action,
+ data,
+ authPermission,
+ encryptOptions = {},
+ signingAccount,
+ }: {
account: string,
action: string,
data: any,
- encryptOptions: EncryptOptions = {},
- ): Promise {
+ authPermission?: string,
+ encryptOptions?: EncryptOptions,
+ signingAccount?: string,
+}): Promise {
data.tpid = this.getTechnologyProviderId(data.tpid)
if (data.content && !encryptOptions.key) {
switch (action) {
@@ -1485,12 +1494,14 @@ export class FIOSDK {
//
}
}
- const pushTransaction = new SignedTransactions.PushTransaction(
+ const pushTransaction = new SignedTransactions.PushTransaction({
action,
account,
+ authPermission,
data,
encryptOptions,
- )
+ signingAccount,
+})
return pushTransaction.execute(this.privateKey, this.publicKey, this.returnPreparedTrx)
}
@@ -1774,7 +1785,14 @@ export class FIOSDK {
case 'getMultiplier':
return this.getMultiplier()
case 'pushTransaction':
- return this.pushTransaction(params.account, params.action, params.data, params.encryptOptions)
+ return this.pushTransaction({
+ account: params.account,
+ action: params.action,
+ data: params.data,
+ authPermission: params.authPermission,
+ encryptOptions: params.encryptOptions,
+ signingAccount: params.signingAccount,
+ })
case 'getAccountPubKey':
return this.getAccountPubKey(params.account)
case 'getEncryptKey':
diff --git a/src/entities/Autorization.ts b/src/entities/Autorization.ts
index 61ff8032..10a47d90 100644
--- a/src/entities/Autorization.ts
+++ b/src/entities/Autorization.ts
@@ -1,6 +1,6 @@
export class Autorization {
public actor: string
- public permission: string
+ public permission?: string
constructor(actor: string, permission = 'active') {
this.actor = actor
diff --git a/src/entities/RawAction.ts b/src/entities/RawAction.ts
index 1f279fa3..d68ce86d 100644
--- a/src/entities/RawAction.ts
+++ b/src/entities/RawAction.ts
@@ -5,4 +5,5 @@ export class RawAction {
public name: string = '' // 'transfer',
public authorization: Autorization[] = new Array()
public data: any
+ public actor: string | undefined
}
diff --git a/src/transactions/Transactions.ts b/src/transactions/Transactions.ts
index 53bce89c..2d820ab8 100644
--- a/src/transactions/Transactions.ts
+++ b/src/transactions/Transactions.ts
@@ -92,6 +92,8 @@ export class Transactions {
public validationRules: any | null = null
public expirationOffset: number = Constants.defaultExpirationOffset
+ public authPermission: string | undefined
+ public signingAccount: string | undefined
public getActor(publicKey: string = ''): string {
return Transactions.FioProvider.accountHash((publicKey === '' || !publicKey) ? this.publicKey : publicKey)
@@ -223,16 +225,18 @@ export class Transactions {
}
public async createRawTransaction(
- { account, action, data, publicKey, chainData }: {
+ { account, action, authPermission, data, publicKey, chainData, signingAccount }: {
account: string;
action: string;
- data: any,
- publicKey?: string,
+ authPermission?: string;
+ data: any;
+ publicKey?: string;
chainData?: {
ref_block_num: number,
ref_block_prefix: number,
expiration: string,
- }
+ };
+ signingAccount?: string;
},
): Promise {
const rawTransaction = new RawTransaction()
@@ -244,10 +248,11 @@ export class Transactions {
data.actor = actor
}
- rawaction.authorization.push(new Autorization(data.actor, data.permission))
+ rawaction.authorization.push(new Autorization(data.actor, authPermission))
rawaction.account = account
rawaction.name = action
rawaction.data = data
+ rawaction.actor = signingAccount
rawTransaction.actions.push(rawaction)
if (chainData && chainData.ref_block_num) {
diff --git a/src/transactions/signed/PushTransaction.ts b/src/transactions/signed/PushTransaction.ts
index ebb5bcf7..f62bd6f0 100644
--- a/src/transactions/signed/PushTransaction.ts
+++ b/src/transactions/signed/PushTransaction.ts
@@ -10,18 +10,31 @@ export class PushTransaction extends SignedTransaction {
public ACCOUNT: string = Constants.defaultAccount
public data: any
public encryptOptions: EncryptOptions
+ public authPermission: string | undefined
+ public signingAccount: string | undefined
- constructor(
+ constructor({
+ action,
+ account,
+ authPermission,
+ data,
+ encryptOptions = {},
+ signingAccount,
+ }: {
action: string,
account: string,
+ authPermission: string | undefined,
data: any,
- encryptOptions: EncryptOptions = {},
- ) {
+ encryptOptions: EncryptOptions,
+ signingAccount: string | undefined,
+}) {
super()
this.ACTION = action
if (account) { this.ACCOUNT = account }
this.data = data
this.encryptOptions = encryptOptions
+ this.authPermission = authPermission
+ this.signingAccount = signingAccount
}
public getData(): any {
@@ -38,7 +51,6 @@ export class PushTransaction extends SignedTransaction {
return {
...data,
actor: this.data.actor != null && this.data.actor !== '' ? this.data.actor : this.getActor(),
- permission: this.data.permission || 'active',
}
}
diff --git a/src/transactions/signed/SignedTransaction.ts b/src/transactions/signed/SignedTransaction.ts
index 7679fd1e..e326ea36 100644
--- a/src/transactions/signed/SignedTransaction.ts
+++ b/src/transactions/signed/SignedTransaction.ts
@@ -43,6 +43,8 @@ export abstract class SignedTransaction extends Transactions {
public abstract getData(): any
+ public static authPermission: string | undefined
+ public static signingAccount: string | undefined
public static expirationOffset: number
public async execute(privateKey: string, publicKey: string, dryRun = false, expirationOffset = Constants.defaultExpirationOffset): Promise {
@@ -53,7 +55,9 @@ export abstract class SignedTransaction extends Transactions {
const rawTransaction = await this.createRawTransaction({
account: this.getAccount(),
action: this.getAction(),
+ authPermission: this.getAuthPermission(),
data: this.getData(),
+ signingAccount: this.getSigningAccount(),
})
const result = await this.pushToServer(rawTransaction, this.getEndPoint(), dryRun)
@@ -72,6 +76,14 @@ export abstract class SignedTransaction extends Transactions {
return this.ACCOUNT
}
+ public getAuthPermission(): string | undefined {
+ return this.authPermission
+ }
+
+ public getSigningAccount(): string | undefined {
+ return this.signingAccount
+ }
+
public getEndPoint(): string {
return this.ENDPOINT
}
diff --git a/tests/index.spec.js b/tests/index.spec.js
index 4b7bfce6..e0f1db3f 100644
--- a/tests/index.spec.js
+++ b/tests/index.spec.js
@@ -9,7 +9,13 @@ const fetchJson = async (uri, opts = {}) => {
return fetch(uri, opts)
}
-let privateKey, publicKey, privateKey2, publicKey2, testFioAddressName, testFioAddressName2
+let privateKey,
+ publicKey,
+ privateKey2,
+ publicKey2,
+ testFioAddressName,
+ testFioAddressName2,
+ testFioDomainName
const mnemonic = 'property follow talent guilt uncover someone gain powder urge slot taxi sketch'
const mnemonic2 = 'round work clump little air glue lemon gravity shed charge assault orbit'
@@ -792,6 +798,131 @@ describe('Testing generic actions', () => {
// })
})
+describe('Test addaddress on account with permissions', () => {
+ const account1 = FIOSDK.accountHash(publicKey).accountnm;
+ const account2 = FIOSDK.accountHash(publicKey2).accountnm;
+
+ const permissionName = 'addmyadd'; // Must be < 12 chars
+
+ it(`user1 creates addmyadd permission and assigns to user2`, async () => {
+ try {
+ const authorization_object = {
+ threshold: 1,
+ accounts: [
+ {
+ permission: {
+ actor: account2,
+ permission: 'active',
+ },
+ weight: 1,
+ },
+ ],
+ keys: [],
+ waits: [],
+ };
+
+ const result = await fioSdk.genericAction('pushTransaction', {
+ action: 'updateauth',
+ account: 'eosio',
+ actor: account1,
+ data: {
+ permission: permissionName, //addmyadd
+ parent: 'active',
+ max_fee: defaultFee,
+ auth: authorization_object,
+ account: account1,
+ },
+ });
+
+ expect(result).to.have.all.keys(
+ 'transaction_id',
+ 'block_num',
+ 'block_time'
+ );
+ expect(result.block_num).to.be.a('number');
+ expect(result.transaction_id).to.be.a('string');
+ } catch (e) {
+ console.log(e);
+ }
+ });
+
+ it(`user1 links regmyadd permission to regaddress`, async () => {
+ try {
+ const result = await fioSdk.genericAction('pushTransaction', {
+ action: 'linkauth',
+ account: 'eosio',
+ actor: account1,
+ data: {
+ account: account1, // the owner of the permission to be linked, this account will sign the transaction
+ code: 'fio.address', // the contract owner of the action to be linked
+ type: 'addaddress', // the action to be linked
+ requirement: permissionName, // the name of the custom permission (created by updateauth)
+ max_fee: defaultFee,
+ },
+ });
+
+ expect(result).to.have.all.keys(
+ 'transaction_id',
+ 'block_num',
+ 'block_time'
+ );
+ expect(result.block_num).to.be.a('number');
+ expect(result.transaction_id).to.be.a('string');
+ } catch (e) {
+ console.log(e);
+ }
+ });
+
+ it(`renewdomain for user1`, async () => {
+ try {
+ const result = await fioSdk.genericAction('pushTransaction', {
+ action: 'renewdomain',
+ account: 'fio.address',
+ authPermission: 'active',
+ data: {
+ fio_domain: testFioDomainName,
+ max_fee: defaultFee,
+ tpid: '',
+ actor: account1,
+ },
+ });
+
+ expect(result.status).to.equal('OK');
+ } catch (e) {
+ console.log(e);
+ }
+ });
+
+ it(`addaddress as user2`, async () => {
+ try {
+ const result = await fioSdk.genericAction('pushTransaction', {
+ action: 'addaddress',
+ account: 'fio.address',
+ signingAccount: account2,
+ authPermission: permissionName,
+ data: {
+ fio_address: testFioAddressName,
+ public_addresses: [
+ {
+ chain_code: 'BCH',
+ token_code: 'BCH',
+ public_address:
+ 'bitcoincash:qzf8zha74ahdh9j0xnwlffdn0zuyaslx3c90q7n9g9',
+ },
+ ],
+ max_fee: defaultFee,
+ tpid: '',
+ actor: account1,
+ },
+ });
+
+ expect(result.status).to.equal('OK');
+ } catch (e) {
+ console.log(e);
+ }
+ });
+});
+
describe('Staking tests', () => {
let stakedBalance = 0;
const stakeAmount = FIOSDK.amountToSUF(5);
diff --git a/tests/testnet.spec.js b/tests/testnet.spec.js
index d026e713..b44d8311 100644
--- a/tests/testnet.spec.js
+++ b/tests/testnet.spec.js
@@ -17,7 +17,8 @@ let privateKey = '',
privateKey2 = '',
publicKey2 = '',
testFioAddressName = '',
- testFioAddressName2 = ''
+ testFioAddressName2 = '',
+ testFioDomainName = '';
/**
* Public Testnet API nodes can be found at: https://github.com/fioprotocol/fio.mainnet
@@ -700,6 +701,125 @@ describe('Testing generic actions', () => {
// });
})
+describe('Test addaddress on account with permissions', () => {
+ const account1 = FIOSDK.accountHash(publicKey).accountnm;
+ const account2 = FIOSDK.accountHash(publicKey2).accountnm;
+
+ const permissionName = 'addmyadd'; // Must be < 12 chars
+
+ it(`user1 creates addmyadd permission and assigns to user2`, async () => {
+ try {
+ const authorization_object = {
+ threshold: 1,
+ accounts: [
+ {
+ permission: {
+ actor: account2,
+ permission: 'active',
+ },
+ weight: 1,
+ },
+ ],
+ keys: [],
+ waits: [],
+ };
+
+ const result = await fioSdk.genericAction('pushTransaction', {
+ action: 'updateauth',
+ account: 'eosio',
+ actor: account1,
+ data: {
+ permission: permissionName, //addmyadd
+ parent: 'active',
+ max_fee: defaultFee,
+ auth: authorization_object,
+ account: account1,
+ },
+ });
+
+ expect(result).to.have.all.keys('transaction_id', 'block_num', 'block_time')
+ expect(result.block_num).to.be.a('number')
+ expect(result.transaction_id).to.be.a('string')
+ } catch (e) {
+ console.log(e);
+ }
+ });
+
+ it(`user1 links regmyadd permission to regaddress`, async () => {
+ try {
+ const result = await fioSdk.genericAction('pushTransaction', {
+ action: 'linkauth',
+ account: 'eosio',
+ actor: account1,
+ data: {
+ account: account1, // the owner of the permission to be linked, this account will sign the transaction
+ code: 'fio.address', // the contract owner of the action to be linked
+ type: 'addaddress', // the action to be linked
+ requirement: permissionName, // the name of the custom permission (created by updateauth)
+ max_fee: defaultFee,
+ },
+ });
+
+ expect(result).to.have.all.keys('transaction_id', 'block_num', 'block_time')
+ expect(result.block_num).to.be.a('number')
+ expect(result.transaction_id).to.be.a('string')
+ } catch (e) {
+ console.log(e);
+ }
+ });
+
+ it(`renewdomain for user1`, async () => {
+ try {
+ const result = await fioSdk.genericAction('pushTransaction', {
+ action: 'renewdomain',
+ account: 'fio.address',
+ authPermission: 'active',
+ data: {
+ fio_domain: testFioDomainName,
+ max_fee: defaultFee,
+ tpid: '',
+ actor: account1,
+ },
+ });
+
+ expect(result.status).to.equal('OK');
+ } catch (e) {
+ console.log(e);
+ }
+ });
+
+ /* todo uncomment when the permissions go live in test net
+ it(`addaddress as user2`, async () => {
+ try {
+ const result = await fioSdk.genericAction('pushTransaction', {
+ action: 'addaddress',
+ account: 'fio.address',
+ signingAccount: account2,
+ authPermission: permissionName,
+ data: {
+ fio_address: testFioAddressName,
+ public_addresses: [
+ {
+ chain_code: 'BCH',
+ token_code: 'BCH',
+ public_address:
+ 'bitcoincash:qzf8zha74ahdh9j0xnwlffdn0zuyaslx3c90q7n9g9',
+ },
+ ],
+ max_fee: defaultFee,
+ tpid: '',
+ actor: account1,
+ },
+ });
+ console.log('Result: ', result);
+ expect(result.status).to.equal('OK');
+ } catch (e) {
+ console.log(e);
+ }
+ });
+ */
+});
+
/* todo uncomment when the permissions go live in test net
describe('Testing Fio permissions', () => {
action: string
Name of action