Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
7f26b64
expand comment on MIME data prefix in the construction of ordinal ins…
lamafab Jul 5, 2023
3f47bd6
add NFT module
lamafab Jul 5, 2023
657560c
update comment on push_opcode
lamafab Jul 5, 2023
e8bdb90
add test for NFT inscription
lamafab Jul 5, 2023
7f47e36
expand full list of inscription types
lamafab Jul 6, 2023
5f8eca8
compare NFT inscription test data with expected values
lamafab Jul 6, 2023
d378fcb
avoid splitting expected values into individual consts, use slices di…
lamafab Jul 6, 2023
6964c73
fix warnings
lamafab Jul 6, 2023
d0f6b46
rename new_image to just new
lamafab Jul 6, 2023
2cf3146
add tw_build_nft_inscription FFI function
lamafab Jul 6, 2023
f638ad6
test tw_build_nft_inscription FFI function
lamafab Jul 6, 2023
ec17d25
test protobuf NFT inscriptions
lamafab Jul 6, 2023
2e86ffc
rename ImageType to MimeType
lamafab Jul 6, 2023
30d0324
rename TW::Rust::tw_build_brc20_inscribe_transfer to TW::Rust::tw_bui…
lamafab Jul 7, 2023
ed59769
bitcoin-nft-inscriptions
lamafab Jul 7, 2023
d277601
add Script::buildNftInscription to CXX files, include correct path to…
lamafab Jul 10, 2023
ab2e9dc
add CXX test for SignNftInscription
lamafab Jul 10, 2023
6457bee
add CXX test SignNftInscriptionReveal
lamafab Jul 10, 2023
cf9cd63
expand C interfaces with NFT inscription construction
lamafab Jul 10, 2023
86f3af6
track TWBitcoinOrdinalsMimeType.h
lamafab Jul 10, 2023
7b8c2ad
add Swift tests for NFT inscription
lamafab Jul 11, 2023
f11a7c3
track TWOrdMimeType.h
lamafab Jul 11, 2023
fbcb90e
correctly set payload when reading from file
lamafab Jul 11, 2023
982cf10
compare substrings
lamafab Jul 11, 2023
c51f42c
avoid var name reuse
lamafab Jul 11, 2023
60a725c
add nft inscription hex data of image and expected output
lamafab Jul 11, 2023
c001d94
small cleanup
lamafab Jul 11, 2023
46a3a2d
replace TW::Rust::MimeType with TWOrdMimeType
lamafab Jul 11, 2023
1f8fdf7
pass raw integer to Rust, derived from enum variant
lamafab Jul 12, 2023
e914d59
reverse txId for Swift tests
lamafab Jul 12, 2023
8907a12
trigger CI
lamafab Jul 12, 2023
a1e327a
run cargo fmt
lamafab Jul 12, 2023
55fdd9d
revert Podlock and update rust/coverage.stats
lamafab Jul 12, 2023
1ec2683
update wallet-core-kotlin version in kmp
lamafab Jul 12, 2023
cfb82d6
clear todos
lamafab Jul 13, 2023
565bafb
rename tw_build_nft_inscription to tw_build_ordinal_nft_inscription
lamafab Jul 13, 2023
01ae022
remove Foundation import in Swift tests
lamafab Jul 13, 2023
7955882
add Ordinal prefix to Nft inscriptions where appropriate, deprecate M…
lamafab Jul 13, 2023
4ad8656
pass mime type as string from C++ to Rust
lamafab Jul 13, 2023
3513a67
rename tw_build_ordinal_nft_inscription to tw_bitcoin_build_nft_inscr…
lamafab Jul 13, 2023
d327527
update wallet-core-kotlin
lamafab Jul 13, 2023
3d7e93f
update Pods in samples
lamafab Jul 13, 2023
c2af9e4
Merge branch 'master' into bitcoin-nft-inscriptions
lamafab Jul 13, 2023
27606a5
run cargo fmt
lamafab Jul 13, 2023
5668faa
update pods in swift/ and swift/Example
lamafab Jul 13, 2023
f7c3385
fix how mime type is passed in swift tests
lamafab Jul 13, 2023
2b642ad
pass string directly to Rust functions
lamafab Jul 14, 2023
876bdf0
undo pod changes in samples
lamafab Jul 14, 2023
5c9f7cd
run cargo fmt
lamafab Jul 14, 2023
a72678f
embed image content and raw transaction in CPP file directly
lamafab Jul 17, 2023
9a0b6b9
embed image as raw hex in Rust
lamafab Jul 17, 2023
647bc65
add embedded data in CPP files into separate file
lamafab Jul 17, 2023
03e8607
Merge branch 'embed-nft-data' into bitcoin-nft-inscriptions
lamafab Jul 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions include/TrustWalletCore/TWBitcoinScript.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

#include "TWBase.h"
#include "TWBitcoinSigHashType.h"
#include "TWOrdMimeType.h"
#include "TWCoinType.h"
#include "TWData.h"
#include "TWPublicKey.h"
Expand Down Expand Up @@ -212,7 +211,7 @@ TWData* _Nonnull TWBitcoinScriptBuildBRC20InscribeTransfer(TWString* _Nonnull ti
/// \note Must be deleted with \TWBitcoinScriptDelete
/// \return A pointer to the built script
TW_EXPORT_STATIC_METHOD
TWData* _Nonnull TWBitcoinScriptBuildNftInscription(enum TWOrdMimeType mimeType, TWData *_Nonnull payload, TWData *_Nonnull pubkey);
TWData* _Nonnull TWBitcoinScriptBuildOrdinalNftInscription(TWString* _Nonnull mimeType, TWData* _Nonnull payload, TWData* _Nonnull pubkey);

/// Builds a appropriate lock script for the given address..
///
Expand All @@ -221,7 +220,7 @@ TWData* _Nonnull TWBitcoinScriptBuildNftInscription(enum TWOrdMimeType mimeType,
/// \note Must be deleted with \TWBitcoinScriptDelete
/// \return A pointer to the built script
TW_EXPORT_STATIC_METHOD
struct TWBitcoinScript* _Nonnull TWBitcoinScriptLockScriptForAddress(TWString* _Nonnull address, enum TWCoinType coin);
struct TWBitcoinScript *_Nonnull TWBitcoinScriptLockScriptForAddress(TWString* _Nonnull address, enum TWCoinType coin);

/// Builds a appropriate lock script for the given address with replay.
TW_EXPORT_STATIC_METHOD
Expand Down
41 changes: 0 additions & 41 deletions include/TrustWalletCore/TWOrdMimeType.h

This file was deleted.

3 changes: 2 additions & 1 deletion rust/tw_bitcoin/src/ffi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ pub(crate) fn taproot_build_and_sign_transaction(proto: SigningInput) -> Result<
TrVariant::P2TRKEYPATH => {
TxOutputP2TRKeyPath::new_with_script(satoshis, script_buf).into()
},
// TODO: We could combine the next two variants into a single one.
// We're keeping those two variants separate for now, we're planning
// on writing a new interface as part of a larger task anyway.
TrVariant::BRC20TRANSFER => {
TXOutputP2TRScriptPath::new_with_script(satoshis, script_buf).into()
},
Expand Down
16 changes: 11 additions & 5 deletions rust/tw_bitcoin/src/ffi/scripts.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::brc20::{BRC20TransferInscription, Ticker};
use crate::nft::{MimeType, NftInscription};
use crate::nft::OrdinalNftInscription;
use crate::{
Recipient, TXOutputP2TRScriptPath, TxOutputP2PKH, TxOutputP2TRKeyPath, TxOutputP2WPKH,
};
Expand Down Expand Up @@ -146,15 +146,20 @@ pub unsafe extern "C" fn tw_build_brc20_transfer_inscription(

#[no_mangle]
// Builds the Ordinals inscripton for BRC20 transfer.
pub unsafe extern "C" fn tw_build_nft_inscription(
mime_type: u32,
pub unsafe extern "C" fn tw_bitcoin_build_nft_inscription(
mime_type: *const u8,
mime_type_len: usize,
data: *const u8,
data_len: usize,
satoshis: i64,
pubkey: *const u8,
pubkey_len: usize,
) -> CByteArray {
let mime_type = try_or_else!(MimeType::from_raw(mime_type as usize), CByteArray::null);
// Convert mimeType.
let mime_type = try_or_else!(
CByteArrayRef::new(mime_type, mime_type_len).as_slice(),
CByteArray::null
);

// Convert data to inscribe.
let data = try_or_else!(
Expand All @@ -171,7 +176,8 @@ pub unsafe extern "C" fn tw_build_nft_inscription(
let recipient = try_or_else!(Recipient::<PublicKey>::from_slice(slice), CByteArray::null);

// Inscribe NFT data.
let nft = NftInscription::new(mime_type, data, recipient).expect("TODO");
let nft = OrdinalNftInscription::new(mime_type, data, recipient)
.expect("Ordinal NFT inscription incorrectly constructed");

let tx_out = TXOutputP2TRScriptPath::new(satoshis as u64, nft.inscription().recipient());
let spending_script = nft.inscription().taproot_program();
Expand Down
120 changes: 16 additions & 104 deletions rust/tw_bitcoin/src/nft.rs
Original file line number Diff line number Diff line change
@@ -1,111 +1,23 @@
use crate::ordinals::OrdinalsInscription;
use crate::{Recipient, Result};
use bitcoin::PublicKey;
use std::fmt::Display;

// Available inscription types, as specified in the `ord` repository.
#[repr(C)]
#[derive(Clone, Debug, Copy, Eq, PartialEq)]
pub enum MimeType {
ApplicationJson = 1,
ApplicationPdf = 2,
ApplicationPgpSignature = 3,
ApplicationYaml = 4,
AudioFlac = 5,
AudioMpeg = 6,
AudioWav = 7,
ImageApng = 8,
ImageAvif = 9,
ImageGif = 10,
ImageJpeg = 11,
ImagePng = 12,
ImageSvgXml = 13,
ImageWebp = 14,
ModelGltfBinary = 15,
ModelStl = 16,
TextCss = 17,
TextHtml = 18,
TextJavascript = 19,
TextPlain = 20,
TextMarkdown = 21,
VideoMp4 = 22,
VideoWebm = 23,
}

impl MimeType {
pub fn from_raw(raw: usize) -> Option<Self> {
use MimeType::*;

let res = match raw {
1 => ApplicationJson,
2 => ApplicationPdf,
3 => ApplicationPgpSignature,
4 => ApplicationYaml,
5 => AudioFlac,
6 => AudioMpeg,
7 => AudioWav,
8 => ImageApng,
9 => ImageAvif,
10 => ImageGif,
11 => ImageJpeg,
12 => ImagePng,
13 => ImageSvgXml,
14 => ImageWebp,
15 => ModelGltfBinary,
16 => ModelStl,
17 => TextCss,
18 => TextHtml,
19 => TextJavascript,
20 => TextPlain,
21 => TextMarkdown,
22 => VideoMp4,
23 => VideoWebm,
_ => return None,
};

Some(res)
}
}

impl Display for MimeType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use MimeType::*;

let str = match self {
ApplicationJson => "application/json",
ApplicationPdf => "application/pdf",
ApplicationPgpSignature => "application/pgp-signature",
ApplicationYaml => "application/yaml",
AudioFlac => "audio/flac",
AudioMpeg => "audio/mpeg",
AudioWav => "audio/wav",
ImageApng => "image/apng",
ImageAvif => "image/avif",
ImageGif => "image/gif",
ImageJpeg => "image/jpeg",
ImagePng => "image/png",
ImageSvgXml => "image/svg+xml",
ImageWebp => "image/webp",
ModelGltfBinary => "model/gltf-binary",
ModelStl => "model/stl",
TextCss => "text/css",
TextHtml => "text/html;charset=utf-8",
TextJavascript => "text/javascript",
TextPlain => "text/plain;charset=utf-8",
TextMarkdown => "text/markdown;charset=utf-8",
VideoMp4 => "video/mp4",
VideoWebm => "video/webm",
};

write!(f, "{}", str)
}
}

pub struct NftInscription(OrdinalsInscription);

impl NftInscription {
pub fn new(ty: MimeType, data: &[u8], recipient: Recipient<PublicKey>) -> Result<Self> {
OrdinalsInscription::new(ty.to_string().as_bytes(), data, recipient).map(NftInscription)
pub struct OrdinalNftInscription(OrdinalsInscription);

impl OrdinalNftInscription {
// Constructs an [Ordinal inscription] with a given MIME type. Common MIME
// types are:
// * "application/json",
// * "application/pdf",
// * "image/gif",
// * "image/jpeg",
// * "image/png",
// * "text/plain;charset=utf-8"
// * ...
//
// [Ordinal inscription]: https://docs.ordinals.com/inscriptions.html
pub fn new(mime_type: &[u8], data: &[u8], recipient: Recipient<PublicKey>) -> Result<Self> {
OrdinalsInscription::new(mime_type, data, recipient).map(OrdinalNftInscription)
}
pub fn inscription(&self) -> &OrdinalsInscription {
&self.0
Expand Down
10 changes: 5 additions & 5 deletions rust/tw_bitcoin/src/tests/ffi/nft.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::ffi::taproot_build_and_sign_transaction;
use crate::nft::{MimeType, NftInscription};
use crate::nft::OrdinalNftInscription;
use crate::tests::ffi::utils::{
call_ffi_build_p2wpkh_script, reverse_txid, ProtoSigningInputBuilder, ProtoTransactionBuilder,
};
Expand All @@ -17,15 +17,15 @@ fn proto_nft_inscription_script() {
let keypair: secp256k1::KeyPair = keypair_from_wif(ALICE_WIF).unwrap();
let recipient = Recipient::<PublicKey>::from(keypair);

let mime_type = MimeType::ImagePng;
let mime_type = b"image/png";
let data = include_bytes!("../data/tw_logo.png");
let satoshis: u64 = 1_000;

// Call FFI function.
let ffi_out = call_ffi_build_nft_inscription(satoshis, mime_type, data, &recipient);

// Compare with native call.
let nft = NftInscription::new(mime_type, data, recipient).unwrap();
let nft = OrdinalNftInscription::new(mime_type, data, recipient).unwrap();

let tapscript = nft.inscription().recipient().clone();
let spending_script = nft.inscription().taproot_program();
Expand All @@ -51,7 +51,7 @@ fn proto_sign_nft_inscription_commit() {
let privkey = alice.secret_bytes();
let recipient = Recipient::<PublicKey>::from(&alice);

let mime_type = MimeType::ImagePng;
let mime_type = b"image/png";
let data = include_bytes!("../data/tw_logo.png");
let satoshis: u64 = 1_000;

Expand Down Expand Up @@ -99,7 +99,7 @@ fn proto_sign_nft_inscription_reveal() {
let privkey = alice.secret_bytes();
let recipient = Recipient::<PublicKey>::from(&alice);

let mime_type = MimeType::ImagePng;
let mime_type = b"image/png";
let data = include_bytes!("../data/tw_logo.png");
let satoshis: u64 = 1_000;

Expand Down
12 changes: 6 additions & 6 deletions rust/tw_bitcoin/src/tests/ffi/utils.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use crate::ffi::{
tw_build_brc20_transfer_inscription, tw_build_nft_inscription, tw_build_p2pkh_script,
tw_bitcoin_build_nft_inscription, tw_build_brc20_transfer_inscription, tw_build_p2pkh_script,
tw_build_p2tr_key_path_script, tw_build_p2wpkh_script,
};
use crate::nft::MimeType;
use crate::Recipient;
use bitcoin::PublicKey;
use std::borrow::Cow;
Expand Down Expand Up @@ -125,20 +124,21 @@ pub fn call_ffi_build_brc20_transfer_script<'a, 'b>(
}
}

/// Convenience wrapper over `tw_build_nft_inscription` with Protobuf
/// Convenience wrapper over `tw_bitcoin_build_nft_inscription` with Protobuf
/// deserialization support.
pub fn call_ffi_build_nft_inscription<'a, 'b>(
satoshis: u64,
mime_type: MimeType,
mime_type: &[u8],
data: &[u8],
// We use 'b to clarify that `recipient` is not tied to the return value.
recipient: &'b Recipient<PublicKey>,
) -> TransactionOutput<'a> {
let pubkey = recipient.public_key().to_bytes();

let raw = unsafe {
tw_build_nft_inscription(
mime_type as u32,
tw_bitcoin_build_nft_inscription(
mime_type.as_ptr(),
mime_type.len(),
data.as_ptr(),
data.len(),
satoshis as i64,
Expand Down
4 changes: 2 additions & 2 deletions rust/tw_bitcoin/src/tests/nft.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::nft::{MimeType, NftInscription};
use crate::nft::OrdinalNftInscription;
use crate::{
keypair_from_wif, TXOutputP2TRScriptPath, TransactionBuilder, TxInputP2TRScriptPath,
TxInputP2WPKH, TxOutputP2WPKH,
Expand Down Expand Up @@ -30,7 +30,7 @@ fn inscribe_nft() {
let mut content = vec![];
file.read_to_end(&mut content).unwrap();

let nft_inscription = NftInscription::new(MimeType::ImagePng, &content, alice.into()).unwrap();
let nft_inscription = OrdinalNftInscription::new(b"image/png", &content, alice.into()).unwrap();

let txid = Txid::from_str(COMMIT_TXID).unwrap();

Expand Down
16 changes: 8 additions & 8 deletions samples/kmp/iosApp/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
PODS:
- shared (1.0):
- TrustWalletCore
- SwiftProtobuf (1.19.1)
- TrustWalletCore (2.9.8):
- TrustWalletCore/Core (= 2.9.8)
- TrustWalletCore/Core (2.9.8):
- SwiftProtobuf (1.22.0)
- TrustWalletCore (3.2.5):
- TrustWalletCore/Core (= 3.2.5)
- TrustWalletCore/Core (3.2.5):
- TrustWalletCore/Types
- TrustWalletCore/Types (2.9.8):
- TrustWalletCore/Types (3.2.5):
- SwiftProtobuf

DEPENDENCIES:
Expand All @@ -23,9 +23,9 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
shared: 973e5c894781ebff8382176ea25326e62f08b171
SwiftProtobuf: 59d9ea2eb5f84b509f32d170a65f3348ae758f1e
TrustWalletCore: 53f09313edb1c010de78314d023c67d2d4654864
SwiftProtobuf: 40bd808372cb8706108f22d28f8ab4a6b9bc6989
TrustWalletCore: 0e99669adf6134bc5e5579f1f85727efd8f9f282

PODFILE CHECKSUM: f282da88f39e69507b0a255187c8a6b644477756

COCOAPODS: 1.11.3
COCOAPODS: 1.12.1
2 changes: 1 addition & 1 deletion samples/kmp/shared/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ kotlin {
sourceSets {
val commonMain by getting {
dependencies {
implementation("com.trustwallet:wallet-core-kotlin:3.2.3")
implementation("com.trustwallet:wallet-core-kotlin:3.2.5")
}
}
val commonTest by getting {
Expand Down
Loading