From da43540fffe02f5c0ebfabaa3efe0ce160228ab3 Mon Sep 17 00:00:00 2001 From: Samuel Sramko Date: Wed, 26 May 2021 14:46:27 +0200 Subject: [PATCH] Flow NFT support - read methods --- package.json | 2 +- src/transaction/flow.spec.ts | 12 +++++++++++- src/transaction/flow.ts | 23 ++++++++++++++++++++++ src/transaction/flowTransaction/index.ts | 25 ++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index b3a74cae66..6e3b15126a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@tatumio/tatum", - "version": "1.14.1", + "version": "1.14.2", "description": "", "main": "dist/src/index.js", "repository": "https://github.com/tatumio/tatum-js", diff --git a/src/transaction/flow.spec.ts b/src/transaction/flow.spec.ts index 4d3ab3fcf2..9a1cb33f27 100644 --- a/src/transaction/flow.spec.ts +++ b/src/transaction/flow.spec.ts @@ -1,5 +1,5 @@ import {Currency, TransferFlow} from '../model'; -import {flowAddPublicKeyToAccount, flowCreateAccountFromPublicKey, flowSendTransaction} from './flow'; +import {flowAddPublicKeyToAccount, flowCreateAccountFromPublicKey, flowSendTransaction, getFlowNftMetadata, getFlowNftTokenByAddress} from './flow'; describe('Flow tests', () => { @@ -29,4 +29,14 @@ describe('Flow tests', () => { const result = await flowSendTransaction(true, body); expect(result.txId).toBeDefined(); }); + + it.skip('should get NFT token by address', async () => { + const result = await getFlowNftTokenByAddress(true, '0x21cbd745a4df66f1', '1'); + expect(result).toBeDefined(); + }); + + it.skip('should get NFT token metadata', async () => { + const result = await getFlowNftMetadata(true, '0x21cbd745a4df66f1', '1', '1'); + expect(result).toBeDefined(); + }); }); diff --git a/src/transaction/flow.ts b/src/transaction/flow.ts index 2f262e0342..64ab80c9cf 100644 --- a/src/transaction/flow.ts +++ b/src/transaction/flow.ts @@ -14,11 +14,13 @@ import {Currency, FlowBurnNft, FlowMintMultipleNft, FlowMintNft, FlowTransferNft import {generatePrivateKeyFromMnemonic} from '../wallet'; import { burnFlowNftTokenTxTemplate, + metadataFlowNftTokenScript, mintFlowMultipleNftTokenTxTemplate, mintFlowNftTokenTxTemplate, prepareAddPublicKeyToAccountTxTemplate, prepareCreateAccountWithFUSDFromPublicKeyTxTemplate, prepareTransferFlowTxTemplate, + tokenByAddressFlowNftTokenScript, transferFlowNftTokenTxTemplate } from './flowTransaction'; @@ -129,6 +131,15 @@ const sendTransaction = async (testnet: boolean, { }; }; +const sendScript = async (testnet: boolean, code: string, args: Argument[]) => { + fcl.config().put('accessNode.api', testnet ? 'https://access-testnet.onflow.org' : 'https://access-mainnet-beta.onflow.org'); + const response = await fcl.send([ + fcl.script(code), + fcl.args(args.map(arg => fcl.arg(arg.value, types[arg.type]))), + ]); + return fcl.decode(response); +}; + export const flowSignKMSTransaction = async (tx: TransactionKMS, privateKeys: string[], testnet: boolean) => { if (tx.chain !== Currency.FLOW) { throw Error('Unsupported chain.'); @@ -188,6 +199,18 @@ export const flowAddPublicKeyToAccount = async (testnet: boolean, publicKey: str return {txId: result.id, address: result.events[0].data.address}; }; +export const getFlowNftMetadata = async (testnet: boolean, account: string, id: string, tokenType: string) => { + const code = metadataFlowNftTokenScript(testnet); + const args = [{type: 'Address', value: account}, {type: 'UInt64', value: id}, {type: 'String', value: tokenType}]; + return await sendScript(testnet, code, args); +}; + +export const getFlowNftTokenByAddress = async (testnet: boolean, account: string, tokenType: string) => { + const code = tokenByAddressFlowNftTokenScript(testnet); + const args = [{type: 'Address', value: account}, {type: 'String', value: tokenType}]; + return await sendScript(testnet, code, args); +}; + export const sendFlowNftMintToken = async (testnet: boolean, body: FlowMintNft): Promise<{ txId: string }> => { await validateBody(body, FlowMintNft); diff --git a/src/transaction/flowTransaction/index.ts b/src/transaction/flowTransaction/index.ts index 1db0ae1e59..0a86e93039 100644 --- a/src/transaction/flowTransaction/index.ts +++ b/src/transaction/flowTransaction/index.ts @@ -24,6 +24,31 @@ transaction(type: String) { } }`; +export const metadataFlowNftTokenScript = (testnet: boolean) => ` +import TatumMultiNFT from ${testnet ? FLOW_TESTNET_ADDRESSES.TatumMultiNFT : FLOW_MAINNET_ADDRESSES.TatumMultiNFT} + +pub fun main(account: Address, id: UInt64, type: String): String { + let collectionRef = getAccount(account) + .getCapability(TatumMultiNFT.CollectionPublicPath) + .borrow<&{TatumMultiNFT.TatumMultiNftCollectionPublic}>() + ?? panic("Could not borrow capability from public collection") + + return collectionRef.getMetadata(id: id, type: type) +}`; + + +export const tokenByAddressFlowNftTokenScript = (testnet: boolean) => ` +import TatumMultiNFT from ${testnet ? FLOW_TESTNET_ADDRESSES.TatumMultiNFT : FLOW_MAINNET_ADDRESSES.TatumMultiNFT} + +pub fun main(address: Address, type: String): [UInt64] { + let collectionRef = getAccount(address) + .getCapability(TatumMultiNFT.CollectionPublicPath) + .borrow<&{TatumMultiNFT.TatumMultiNftCollectionPublic}>() + ?? panic("Could not borrow capability from public collection") + + return collectionRef.getIDs(type: type) +}`; + export const mintFlowNftTokenTxTemplate = (testnet: boolean) => ` import TatumMultiNFT from ${testnet ? FLOW_TESTNET_ADDRESSES.TatumMultiNFT : FLOW_MAINNET_ADDRESSES.TatumMultiNFT}