generated from PolymeshAssociation/typescript-boilerplate
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b548c71
commit a5d59c0
Showing
7 changed files
with
191 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import BigNumber from 'bignumber.js'; | ||
import sinon from 'sinon'; | ||
|
||
import { prepareTransferPolyX, TransferPolyXParams } from '~/api/procedures/transferPolyX'; | ||
import { Context } from '~/context'; | ||
import { polkadotMockUtils, procedureMockUtils } from '~/testUtils/mocks'; | ||
import { Mocked } from '~/testUtils/types'; | ||
import * as utilsModule from '~/utils'; | ||
|
||
describe('transferPolyX procedure', () => { | ||
let mockContext: Mocked<Context>; | ||
const someDid = 'someDid'; | ||
|
||
beforeAll(() => { | ||
polkadotMockUtils.initMocks(); | ||
procedureMockUtils.initMocks(); | ||
sinon.stub(utilsModule, 'valueToDid').returns(someDid); | ||
sinon.stub(utilsModule, 'stringToAccountKey').returns(polkadotMockUtils.createMockAccountKey()); | ||
}); | ||
|
||
beforeEach(() => { | ||
mockContext = polkadotMockUtils.getContextInstance(); | ||
}); | ||
|
||
afterEach(() => { | ||
procedureMockUtils.reset(); | ||
polkadotMockUtils.reset(); | ||
}); | ||
|
||
afterAll(() => { | ||
procedureMockUtils.cleanup(); | ||
polkadotMockUtils.cleanup(); | ||
}); | ||
|
||
test('should throw an error if the user has insufficient balance to transfer', () => { | ||
const proc = procedureMockUtils.getInstance<TransferPolyXParams, void>(); | ||
proc.context = mockContext; | ||
|
||
return expect( | ||
prepareTransferPolyX.call(proc, { | ||
to: 'someAccount', | ||
amount: new BigNumber(101), | ||
}) | ||
).rejects.toThrow('Insufficient balance to perform this action'); | ||
}); | ||
|
||
test('should throw an error if destination account has not an associated identity', () => { | ||
polkadotMockUtils.createQueryStub('identity', 'keyToIdentityIds', { returnValue: {} }); | ||
|
||
const proc = procedureMockUtils.getInstance<TransferPolyXParams, void>(); | ||
proc.context = mockContext; | ||
|
||
return expect( | ||
prepareTransferPolyX.call(proc, { to: 'someAccount', amount: new BigNumber(99) }) | ||
).rejects.toThrow('The destination account has not an associated identity'); | ||
}); | ||
|
||
test('should add a balance transfer transaction to the queue', async () => { | ||
const amount = new BigNumber(99); | ||
const rawBalance = polkadotMockUtils.createMockBalance(amount.toNumber()); | ||
|
||
polkadotMockUtils.createQueryStub( | ||
'identity', | ||
'keyToIdentityIds', | ||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type | ||
{ returnValue: { unwrap: () => ({ asUnique: '012abc' }) } } | ||
); | ||
|
||
sinon.stub(utilsModule, 'numberToBalance').returns(rawBalance); | ||
|
||
const tx = polkadotMockUtils.createTxStub('balances', 'transfer'); | ||
const proc = procedureMockUtils.getInstance<TransferPolyXParams, void>(); | ||
proc.context = mockContext; | ||
|
||
await prepareTransferPolyX.call(proc, { | ||
to: 'someAccount', | ||
amount, | ||
}); | ||
|
||
sinon.assert.calledWith( | ||
procedureMockUtils.getAddTransactionStub(), | ||
tx, | ||
{}, | ||
someDid, | ||
rawBalance | ||
); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import BigNumber from 'bignumber.js'; | ||
|
||
import { Identity } from '~/api/entities/Identity'; | ||
import { PolymeshError, Procedure } from '~/base'; | ||
import { ErrorCode } from '~/types'; | ||
import { numberToBalance, stringToAccountKey, valueToDid } from '~/utils'; | ||
|
||
export interface TransferPolyXParams { | ||
to: string | Identity; | ||
amount: BigNumber; | ||
} | ||
|
||
/** | ||
* @hidden | ||
*/ | ||
export async function prepareTransferPolyX( | ||
this: Procedure<TransferPolyXParams>, | ||
args: TransferPolyXParams | ||
): Promise<void> { | ||
const { | ||
context: { | ||
polymeshApi: { | ||
query: { identity }, | ||
tx, | ||
}, | ||
}, | ||
context, | ||
} = this; | ||
|
||
const { to: dest, amount: val } = args; | ||
const to = valueToDid(dest); | ||
|
||
const freeBalance = await context.accountBalance(); | ||
|
||
if (val.isGreaterThan(freeBalance)) { | ||
throw new PolymeshError({ | ||
code: ErrorCode.ValidationError, | ||
message: 'Insufficient balance to perform this action', | ||
}); | ||
} | ||
|
||
try { | ||
const identityIds = await identity.keyToIdentityIds(stringToAccountKey(to, context)); | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
const did = identityIds.unwrap().asUnique; | ||
|
||
this.addTransaction(tx.balances.transfer, {}, to, numberToBalance(val, context)); | ||
} catch (err) { | ||
throw new PolymeshError({ | ||
code: ErrorCode.FatalError, | ||
message: 'The destination account has not an associated identity', | ||
}); | ||
} | ||
} | ||
|
||
export const transferPolyX = new Procedure(prepareTransferPolyX); |