Skip to content

Commit

Permalink
Snip20 transfer history query (#153)
Browse files Browse the repository at this point in the history
* feat: snip20 transfer history query

* chore: update transfer ids in mock

* docs: comments and docs site update

* chore: add changeset

* docs: fix typo

* feat: improved error handling on transaction history queries
  • Loading branch information
AustinWoetzel authored Jun 5, 2024
1 parent ed5f747 commit 1cc4633
Show file tree
Hide file tree
Showing 10 changed files with 429 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/red-seahorses-cough.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@shadeprotocol/shadejs": patch
---

snip20 transfer history query
40 changes: 40 additions & 0 deletions docs/queries/snip20.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,43 @@ type TransactionHistory = {
totalTransactions?: number,
blockHeight: number,
}
```

## Get Transfer History
This query is used for legacy snip20s that do not support the newer transaction history query.

**input**

```ts
async function querySnip20TransferHistory({
queryRouterContractAddress,
queryRouterCodeHash,
lcdEndpoint,
chainId,
snip20ContractAddress,
snip20CodeHash,
ownerAddress,
viewingKey,
page,
pageSize,
minBlockHeightValidationOptions,
}:{
queryRouterContractAddress: string,
queryRouterCodeHash?: string,
lcdEndpoint?: string,
chainId?: string,
snip20ContractAddress: string,
snip20CodeHash: string,
ownerAddress: string,
viewingKey: string,
page: number,
pageSize: number,
minBlockHeightValidationOptions?: MinBlockHeightValidationOptions,
}): Promise<TransactionHistory>
```

**output**

```ts
see querySnip20TransactionHistory for output type
```
95 changes: 93 additions & 2 deletions src/contracts/services/snip20.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import {
querySnip20TransactionHistory$,
querySnip20TransactionHistory,
parseSnip20TransactionHistoryResponse,
querySnip20TransferHistory$,
querySnip20TransferHistory,
parseSnip20TransferHistoryResponse,
} from '~/contracts/services/snip20';
import {
test,
Expand All @@ -26,7 +29,9 @@ import { batchSnip20TransactionHistoryUnparsed } from '~/test/mocks/snip20/trans
import { of } from 'rxjs';
import balanceResponse from '~/test/mocks/snip20/balanceResponse.json';
import { transactionHistoryParsed } from '~/test/mocks/snip20/transactionHistory/batchQueryTransactionHistoryParsed';
import { batchSnip20TransactionHistoryWithViewingKeyErrorUnparsed } from '~/test/mocks/snip20/transactionHistory/batchQueryTransactionHistoryWithViewingKeyErrorUnparsed';
import { batchSnip20TransactionHistoryWithViewingKeyErrorUnparsed } from '~/test/mocks/snip20/batchQueryTransactionHistoryWithViewingKeyErrorUnparsed';
import { batchSnip20TransferHistoryUnparsed } from '~/test/mocks/snip20/transferHistory/batchQueryTransferHistoryUnparsed';
import { transferHistoryParsed } from '~/test/mocks/snip20/transferHistory/batchQueryTransferHistoryParsed';

const sendSecretClientContractQuery$ = vi.hoisted(() => vi.fn());
const batchQuery$ = vi.hoisted(() => vi.fn());
Expand All @@ -38,6 +43,7 @@ beforeAll(() => {
tokenInfo: vi.fn(() => 'TOKEN_INFO_MSG'),
getBalance: vi.fn(() => 'GET_BALANCE_MSG'),
getTransactionHistory: vi.fn(() => 'GET_TRANSACTION_HISTORY_MSG'),
getTransferHistory: vi.fn(() => 'GET_TRANSFER_HISTORY_MSG'),
},
},
}));
Expand Down Expand Up @@ -73,12 +79,18 @@ test('it can parse the batch snip20 token info query', () => {
)).toStrictEqual(batchTokensInfoParsed);
});

test('it can parse the batch snip20 token info query', () => {
test('it can parse the snip20 transaction history query', () => {
expect(parseSnip20TransactionHistoryResponse(
batchSnip20TransactionHistoryUnparsed,
)).toStrictEqual(transactionHistoryParsed);
});

test('it can parse the snip20 transfer history query', () => {
expect(parseSnip20TransferHistoryResponse(
batchSnip20TransferHistoryUnparsed,
)).toStrictEqual(transferHistoryParsed);
});

test('it can call the snip20 token info query', async () => {
const input = {
snip20ContractAddress: 'CONTRACT_ADDRESS',
Expand Down Expand Up @@ -297,3 +309,82 @@ test('it can handle the viewing key error on the snip20 transaction history quer

await expect(() => querySnip20TransactionHistory(input)).rejects.toThrowError('Wrong viewing key for this address or viewing key not set');
});

test('it can call the snip20 transfer history query', async () => {
const input = {
queryRouterContractAddress: 'CONTRACT_ADDRESS',
queryRouterCodeHash: 'CODE_HASH',
lcdEndpoint: 'LCD_ENDPOINT',
chainId: 'CHAIN_ID',
snip20ContractAddress: 'MOCK_ADDRESS',
snip20CodeHash: 'MOCK_CODE_HASH',
ownerAddress: 'OWNER_ADDRESS',
viewingKey: 'VIEWING_KEY',
page: 1,
pageSize: 1,
};

// observables function
batchQuery$.mockReturnValueOnce(of(batchSnip20TransferHistoryUnparsed));
let output;
querySnip20TransferHistory$(input).subscribe({
next: (response) => {
output = response;
},
});

expect(batchQuery$).toHaveBeenCalledWith({
contractAddress: input.queryRouterContractAddress,
codeHash: input.queryRouterCodeHash,
lcdEndpoint: input.lcdEndpoint,
chainId: input.chainId,
queries: [{
id: input.snip20ContractAddress,
contract: {
address: input.snip20ContractAddress,
codeHash: input.snip20CodeHash,
},
queryMsg: 'GET_TRANSFER_HISTORY_MSG',
}],
});

expect(output).toStrictEqual(transferHistoryParsed);

// async/await function
batchQuery$.mockReturnValueOnce(of(batchSnip20TransferHistoryUnparsed));
const response = await querySnip20TransferHistory(input);
expect(batchQuery$).toHaveBeenCalledWith({
contractAddress: input.queryRouterContractAddress,
codeHash: input.queryRouterCodeHash,
lcdEndpoint: input.lcdEndpoint,
chainId: input.chainId,
queries: [{
id: input.snip20ContractAddress,
contract: {
address: input.snip20ContractAddress,
codeHash: input.snip20CodeHash,
},
queryMsg: 'GET_TRANSFER_HISTORY_MSG',
}],
});
expect(response).toStrictEqual(transferHistoryParsed);
});

test('it can handle the viewing key error on the snip20 transfer history query', async () => {
const input = {
queryRouterContractAddress: 'CONTRACT_ADDRESS',
queryRouterCodeHash: 'CODE_HASH',
lcdEndpoint: 'LCD_ENDPOINT',
chainId: 'CHAIN_ID',
snip20ContractAddress: 'MOCK_ADDRESS',
snip20CodeHash: 'MOCK_CODE_HASH',
ownerAddress: 'OWNER_ADDRESS',
viewingKey: 'VIEWING_KEY',
page: 1,
pageSize: 1,
};

batchQuery$.mockReturnValueOnce(of(batchSnip20TransactionHistoryWithViewingKeyErrorUnparsed));

await expect(() => querySnip20TransferHistory(input)).rejects.toThrowError('Wrong viewing key for this address or viewing key not set');
});
Loading

0 comments on commit 1cc4633

Please sign in to comment.