{"id":20170685,"url":"https://github.com/bitcoinschema/go-1sat-ord","last_synced_at":"2025-04-10T02:28:15.773Z","repository":{"id":143198268,"uuid":"612748149","full_name":"BitcoinSchema/go-1sat-ord","owner":"BitcoinSchema","description":"1Sat ordinals library for Go","archived":false,"fork":false,"pushed_at":"2023-12-19T12:57:09.000Z","size":40,"stargazers_count":7,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-06-20T13:33:52.650Z","etag":null,"topics":["1sat","bitcoin","bitcoinsv","bsv","ordinals"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BitcoinSchema.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-11T21:21:31.000Z","updated_at":"2024-04-10T08:05:38.000Z","dependencies_parsed_at":"2023-12-19T15:17:59.141Z","dependency_job_id":"3249598d-0ab2-4bb5-8fa3-29c3f2581891","html_url":"https://github.com/BitcoinSchema/go-1sat-ord","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BitcoinSchema%2Fgo-1sat-ord","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BitcoinSchema%2Fgo-1sat-ord/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BitcoinSchema%2Fgo-1sat-ord/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BitcoinSchema%2Fgo-1sat-ord/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BitcoinSchema","download_url":"https://codeload.github.com/BitcoinSchema/go-1sat-ord/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224548356,"owners_count":17329627,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["1sat","bitcoin","bitcoinsv","bsv","ordinals"],"created_at":"2024-11-14T01:20:15.312Z","updated_at":"2025-04-10T02:28:15.750Z","avatar_url":"https://github.com/BitcoinSchema.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# go-1sat-ord\n\nA Go package for creating and managing 1Sat Ordinal inscriptions and transactions using bsv-blockchain/go-sdk and bitcoin-sv/go-templates.\n\n## Description\n\nThis library provides functionality for working with Bitcoin SV ordinals, including:\n\n- Creating ordinal inscriptions\n- Sending ordinals to new addresses\n- Managing regular UTXOs for payments\n- BSV21 token deployment and transfers\n- Ordinal marketplace functionality (listing, purchasing, canceling)\n- Burning ordinals (removing them from circulation)\n- Helper functions for fetching UTXOs from APIs\n- Utility functions for token UTXO selection and subtype data validation\n\n## Installation\n\n```bash\ngo get github.com/bitcoinschema/go-1sat-ord\n```\n\n## Usage\n\n```go\nimport (\n    \"github.com/bitcoinschema/go-1sat-ord\"\n    \"github.com/bsv-blockchain/go-sdk/primitives/ec\"\n)\n\n// Create a private key for payment\npaymentPk, _ := ec.NewPrivateKey()\n// Create a private key for ordinals\nordPk, _ := ec.NewPrivateKey()\n```\n\n### Create Ordinals\n\n```go\n// Prepare utxos to use for transaction fee\nutxos := []*ordinals.Utxo{\n    {\n        TxID:         \"txid\",\n        Vout:         0,\n        ScriptPubKey: \"script\",\n        Satoshis:     100000,\n    },\n}\n\n// Create a destination with inscription\ndestination := \u0026ordinals.Destination{\n    Address: \"destination_address\",\n    File: \u0026ordinals.File{\n        Content:     []byte(\"Hello, world!\"),\n        ContentType: \"text/plain\",\n    },\n    // Optional MAP protocol metadata\n    Metadata: map[string][]byte{\n        \"key\": []byte(\"value\"),\n    },\n}\n\n// If you want to omit metadata from this inscription\n// This creates a smaller output with just the P2PKH script\n// destination.SetOmitMetadata(true)\n\n// Configure the inscription\nconfig := \u0026ordinals.CreateOrdinalsConfig{\n    Utxos:        utxos,\n    Destinations: []*ordinals.Destination{destination},\n    PaymentPk:    paymentPk,\n    ChangeAddress: \"change_address\",\n    // Optional additional payments\n    AdditionalPayments: []*ordinals.PayToAddress{\n        {\n            Address:  \"payment_address\",\n            Satoshis: 5000,\n        },\n    },\n}\n\n// Create the transaction\ntx, err := ordinals.CreateOrdinals(config)\nif err != nil {\n    // Handle error\n}\n\n// Broadcast the transaction\nresult, err := tx.Broadcast(ordinals.OneSatBroadcaster())\nif err != nil {\n    // Handle error\n}\n```\n\n### Send Ordinals\n\n```go\n// Create a destination for the ordinal\ndestination := \u0026ordinals.Destination{\n    Address: \"destination_address\",\n    // Optional: include a new file to reinscribe\n    File: \u0026ordinals.File{\n        Content:     []byte(\"New inscription content\"),\n        ContentType: \"text/plain\",\n    },\n    // Optional: include metadata\n    Metadata: map[string][]byte{\n        \"app\":  []byte(\"myapp\"),\n        \"type\": []byte(\"ord\"),\n    },\n}\n\n// If you want to omit metadata from this inscription\n// destination.SetOmitMetadata(true)\n\n// Configure the send\nconfig := \u0026ordinals.SendOrdinalsConfig{\n    PaymentUtxos:  paymentUtxos,\n    Ordinals:      ordinalUtxos,\n    PaymentPk:     paymentPk,\n    OrdPk:         ordPk,\n    Destinations:  []*ordinals.Destination{destination},\n    ChangeAddress: \"change_address\",\n    // Optional: Control whether number of destinations must match number of ordinals\n    // Default is true, set to false to allow different counts\n    EnforceUniformSend: true,\n    // Optional: Include additional payments in the transaction\n    AdditionalPayments: []*ordinals.PayToAddress{\n        {\n            Address:  \"payment_address\",\n            Satoshis: 5000,\n        },\n    },\n}\n\n// Create the transaction\ntx, err := ordinals.SendOrdinals(config)\nif err != nil {\n    // Handle error\n}\n\n// Broadcast the transaction\nresult, err := tx.Broadcast(ordinals.OneSatBroadcaster())\nif err != nil {\n    // Handle error\n}\n```\n\n### Deploy BSV21 Token\n\n```go\n// Configure the token deployment\nconfig := \u0026ordinals.DeployBsv21TokenConfig{\n    Symbol: \"TOKEN\",\n    Icon:   \"icon_id\",\n    Utxos:  utxos,\n    InitialDistribution: \u0026ordinals.TokenDistribution{\n        Address: \"destination_address\",\n        Tokens:  1000,\n    },\n    PaymentPk:          paymentPk,\n    DestinationAddress: \"destination_address\",\n    ChangeAddress:      \"change_address\",\n}\n\n// Create the transaction\ntx, err := ordinals.DeployBsv21Token(config)\nif err != nil {\n    // Handle error\n}\n\n// Broadcast the transaction\nresult, err := tx.Broadcast(ordinals.OneSatBroadcaster())\nif err != nil {\n    // Handle error\n}\n```\n\n### Transfer BSV21 Tokens with Split Configuration\n\n```go\n// Set minimum tokens per split output\nthreshold := 100.0\n\n// Configure token transfer with split configuration\nconfig := \u0026ordinals.TransferBsv21TokenConfig{\n    Protocol:    ordinals.TokenTypeBSV21,\n    TokenID:     \"your-token-id\",\n    Utxos:       paymentUtxos,\n    InputTokens: tokenUtxos,\n    Distributions: []*ordinals.TokenDistribution{\n        {\n            Address: \"recipient-address\",\n            Tokens:  100,\n            // Optional: Omit metadata from this distribution output\n            // This creates a smaller output with just the P2PKH script\n            OmitMetadata: true,\n        },\n    },\n    PaymentPk:     paymentPk,\n    OrdPk:         ordPk,\n    ChangeAddress: \"change-address\",\n    TokenInputMode: ordinals.TokenInputModeNeeded, // Or TokenInputModeAll\n    // Split configuration for token change outputs\n    SplitConfig: \u0026ordinals.TokenSplitConfig{\n        // Number of outputs to split the token change into\n        Outputs: 3,\n        // Minimum amount of tokens per output (optional)\n        Threshold: \u0026threshold, // where threshold is float64\n        // Omit metadata from change outputs (optional)\n        // This creates smaller outputs with just the P2PKH script\n        OmitMetadata: true,\n    },\n}\n\n// Create the transaction\ntx, err := ordinals.TransferOrdTokens(config)\nif err != nil {\n    // Handle error\n}\n\n// Broadcast the transaction\nresult, err := tx.Broadcast(ordinals.OneSatBroadcaster())\nif err != nil {\n    // Handle error\n}\n```\n\n### Burn Ordinals\n\n```go\n// Configure the ordinal burning\nconfig := \u0026ordinals.BurnOrdinalsConfig{\n    // Payment UTXOs for transaction fees\n    PaymentUtxos: paymentUtxos,\n    PaymentPk:    paymentPk,\n    // Ordinals to burn\n    Ordinals: nftUtxos,\n    OrdPk:    ordPk,\n    // Change address for leftover satoshis from payment utxos\n    ChangeAddress: \"change_address\",\n    // Optional MAP protocol metadata\n    Metadata: map[string][]byte{\n        \"app\":  []byte(\"myapp\"),\n        \"type\": []byte(\"ord\"),\n        \"op\":   []byte(\"burn\"),\n    },\n}\n\n// Create the transaction\ntx, err := ordinals.BurnOrdinals(config)\nif err != nil {\n    // Handle error\n}\n\n// Broadcast the transaction\nresult, err := tx.Broadcast(ordinals.OneSatBroadcaster())\nif err != nil {\n    // Handle error\n}\n```\n\n### Token Marketplace Functions\n\n#### Create Token Listings\n\n```go\n// Configure the token listings\nconfig := \u0026ordinals.CreateOrdTokenListingsConfig{\n    Utxos: paymentUtxos,\n    Listings: []*struct {\n        PayAddress  string\n        Price       uint64\n        ListingUtxo *ordinals.TokenUtxo\n        OrdAddress  string\n    }{\n        {\n            PayAddress:  \"seller_payment_address\",\n            Price:       1000000, // Price in satoshis\n            ListingUtxo: tokenUtxo,\n            OrdAddress:  \"seller_address\",\n        },\n    },\n    PaymentPk:     paymentPk,\n    OrdPk:         ordPk,\n    ChangeAddress: \"change_address\",\n}\n\n// Create the transaction\ntx, err := ordinals.CreateOrdTokenListings(config)\nif err != nil {\n    // Handle error\n}\n\n// Broadcast the transaction\nresult, err := tx.Broadcast(ordinals.OneSatBroadcaster())\nif err != nil {\n    // Handle error\n}\n```\n\n#### Purchase Token Listing\n\n```go\n// Configure the token purchase\nconfig := \u0026ordinals.PurchaseOrdTokenListingConfig{\n    Protocol:    ordinals.TokenTypeBSV21,\n    TokenID:     \"token_id\",\n    Utxos:       paymentUtxos,\n    PaymentPk:   paymentPk,\n    ListingUtxo: tokenUtxo,\n    OrdAddress:  \"buyer_address\",\n    // Optional additional payments\n    AdditionalPayments: []*ordinals.PayToAddress{\n        {\n            Address:  \"fee_recipient_address\",\n            Satoshis: 10000,\n        },\n    },\n    ChangeAddress: \"change_address\",\n}\n\n// Create the transaction\ntx, err := ordinals.PurchaseOrdTokenListing(config)\nif err != nil {\n    // Handle error\n}\n\n// Broadcast the transaction\nresult, err := tx.Broadcast(ordinals.OneSatBroadcaster())\nif err != nil {\n    // Handle error\n}\n```\n\n#### Cancel Token Listings\n\n```go\n// Configure the token listing cancellation\nconfig := \u0026ordinals.CancelOrdTokenListingsConfig{\n    Utxos:        paymentUtxos,\n    ListingUtxos: tokenListingUtxos,\n    OrdPk:        ordPk,\n    PaymentPk:    paymentPk,\n    ChangeAddress: \"change_address\",\n}\n\n// Create the transaction\ntx, err := ordinals.CancelOrdTokenListings(config)\nif err != nil {\n    // Handle error\n}\n\n// Broadcast the transaction\nresult, err := tx.Broadcast(ordinals.OneSatBroadcaster())\nif err != nil {\n    // Handle error\n}\n```\n\n### Helper Functions\n\n#### Fetch UTXOs\n\n```go\n// Fetch UTXOs for payment\npaymentUtxos, err := ordinals.FetchPayUtxos(\"your-payment-address\")\nif err != nil {\n    // Handle error\n}\n\n// Fetch NFT UTXOs\nnftUtxos, err := ordinals.FetchNftUtxos(\"your-nft-address\", \"collection-id\")\nif err != nil {\n    // Handle error\n}\n\n// Fetch token UTXOs\ntokenUtxos, err := ordinals.FetchTokenUtxos(ordinals.TokenTypeBSV21, \"token-id\", \"your-token-address\")\nif err != nil {\n    // Handle error\n}\n```\n\n#### Select Token UTXOs\n\n```go\n// Define selection options\noptions := \u0026ordinals.TokenSelectionOptions{\n    InputStrategy:  ordinals.TokenSelectionStrategyLargestFirst,\n    OutputStrategy: ordinals.TokenSelectionStrategySmallestFirst,\n}\n\n// Select token UTXOs\nresult := ordinals.SelectTokenUtxos(tokenUtxos, 10.5, 8, options)\nif !result.IsEnough {\n    // Not enough tokens available\n    // Handle insufficient funds\n} else {\n    // Use the selected UTXOs\n    selectedUtxos := result.SelectedUtxos\n    totalAmount := result.TotalSelected\n    // Continue with transaction\n}\n```\n\n#### Validate Subtype Data\n\n```go\n// Create subtype data for a collection\ncollectionData := \u0026ordinals.SubTypeData{\n    Description: \"My Collection\",\n    Quantity:    100,\n    Traits: map[string]interface{}{\n        \"category\": \"art\",\n        \"rarity\":   \"common\",\n    },\n}\n\n// Validate collection data\nresult := ordinals.ValidateSubTypeData(ordinals.TokenTypeBSV21, \"collection\", collectionData)\nif !result.Valid {\n    // Handle validation errors\n    for _, err := range result.Errors {\n        fmt.Println(\"Validation error:\", err)\n    }\n} else {\n    // Data is valid, proceed with collection creation\n}\n\n// Create subtype data for a collection item\nitemData := \u0026ordinals.SubTypeData{\n    CollectionID: \"collection123\",\n    MintNumber:   1,\n    Rank:         5,\n    RarityLabel:  \"rare\",\n}\n\n// Validate collection item data\nresult = ordinals.ValidateSubTypeData(ordinals.TokenTypeBSV21, \"collectionItem\", itemData)\nif !result.Valid {\n    // Handle validation errors\n} else {\n    // Data is valid, proceed with item creation\n}\n```\n\n## Testing\n\nThe library includes comprehensive tests for all functionality, including token selection strategies, marketplace operations, and token transfers with various configurations. To run the tests:\n\n```bash\ngo test -v ./...\n```\n\n## Error Handling\n\nThe library provides detailed error messages for common issues:\n\n- Insufficient funds\n- Invalid addresses\n- Script creation errors\n- Token validation failures\n- UTXO fetch failures\n\nAll errors are wrapped with context to help identify the source of the problem.\n\n## More Information\n\n[1Sat Ordinals](https://github.com/bitcoinschema/1sat-ordinals)\n\n## Token Functions\n\n- `DeployToken`: Create a new BSV-20 or BSV-21 token deployment transaction\n- `MintBsv20`: Mint new BSV-20 tokens\n- `TransferOrdTokens`: Transfer BSV-20 or BSV-21 tokens with advanced distribution options","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitcoinschema%2Fgo-1sat-ord","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbitcoinschema%2Fgo-1sat-ord","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitcoinschema%2Fgo-1sat-ord/lists"}